Старатель (Все сообщения пользователя)

Выбрать дату в календареВыбрать дату в календаре

Страницы: 1 2 3 4 5 6 7 8 9 10 11 ... 31 След.
Получение данных из таблиц при автостарте
 
Цитата
Старатель написал:
до подключения к серверу
Цитата
Старатель написал:
при первичном старте скрипт берёт данные из кэша.
Получение данных из таблиц при автостарте
 
Добрый день.

Есть скрипт, который стартует автоматически при запуске 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)
 
Это Антону спасибо!

Цитата
Anton написал:
Не очень удачная конфигурация на мой взгляд
Почему?
luasql (проблема с cursor:fetch)
 
Цитата
Nikolay написал:
блокировки транзакций на уровне базы
C версии 3.7.0 появился режим журнала WAL, в котором, как утверждается, читатели БД и писатели в БД уже не мешают друг другу.

Цитата
Anton написал:
Сам sqlite3 интегрирован в эту же длл, отдельно его добавлять не нужно.
Если не сложно, можете сделать с отдельной sqlite3.dll, чтоб без проблем обновить можно было.
luasql (проблема с cursor:fetch)
 
Цитата
Но к сожалению ссылка http://forum-archive.quik.ru/forum/lua/114488/114488/ на архив с ответом больше не доступна.
Не поможете, вспомните.. как мой вопрос решается??
К сожалению, не помню про что это.
Отладка QUIK 8.8
 
Цитата
Sergey Gorokhov написал:
Действительно в ПО QLUA есть ошибка так же иногда приводящая к завистанию терминала при вызове Lua функции DestroyTable. Мы исправим её в очередном обновлении ПО.
Как скоро?
Временное решение есть?
Отладка QUIK 8.8
 
Sergey Gorokhov, если у вас sleep(1) больше 1 мс, откройте больше окон, чтоб наверняка:
Код
for i = 1, 30 do
Отладка QUIK 8.8
 
Sergey Gorokhov, я не знаю, как у вас не повторяется. Только если ничего не делать.
DestroyTable
Массив (таблица) в OnCalculate
 
В вашем примере результат как раз предсказуем. Главное присвоить элементу nil, а вот если ничего не присвоить
Код
A = {[2] = 1, [3] = 2}
тогда да, непредсказуем.
Массив (таблица) в OnCalculate
 
Цитата
s_mike@rambler.ru написал:
Не используйте unpack, если индикатор может иметь значение Ия nil в любой линии.
Почему?
Почему скрипты в QUIK выполняются дольше
 
Цитата
Anton написал:
Трудно придумать, как арка могла бы это изменить в текущей архитектуре с отдельным мейном.
Делать лок перед началом колбека и анлок по окончании, не?
Появляется лишняя строка в таблице
 
Цитата
Sergey Gorokhov написал:
Цитата
Старатель написал:
При вызове InsertRow / DeleteRow в какой момент происходит смещение индексов?
В смысле?
Что есть DeleteRow (InsertRow)? Это не только удаление (добавление) физической строки, но и смещение всех индексов строк во внутреннем представлении.
Ожидается, что операция смещения строк - цельная. Т.е., если выполнить код в таком порядке:
Код
[callback] InsertRow(id, 1)
[main] SetCell(id, 1, 1, "что-то")
то "что-то" ожидаю увидеть в первой строке, а не чёрт знает где.
Если порядок вызова такой:
Код
[main] SetCell(id, 1, 1, "что-то")
[callback] InsertRow(id, 1)
то запись должна быть либо во второй строке, либо её не должно быть вообще, если таблица на момент SetCell не имела строк.

Что за фантом появляется в виде нулевой строки - не понятно. Отговорки типа "патамушта, мы так захотели" - не объяснение.

Цитата
Sergey Gorokhov написал:
Со стороны QUIK, нет синхронизации.
Дайте скриптеру инструмент синхронизации. Но баг с нулевой строкой в любом случае надо чинить.
Появляется лишняя строка в таблице
 
Цитата
Sergey Gorokhov написал:
Синхронные
При вызове InsertRow / DeleteRow в какой момент происходит смещение индексов?

Цитата
Evgeniy Karnaukhov написал:
Проблема вызвана тем, что работа с таблицей в скрипте осуществляется из разных потоков без синхронизации.
Это чья зона ответственности, скриптера или приложения?
Появляется лишняя строка в таблице
 
Откуда лишняя строка в примере #9?
Появляется лишняя строка в таблице
 
Цитата
Anton написал:
работа с таблицей так или иначе приводит к SendMessage окну (в основной поток то есть)
Что-то никак не пойму, работа с QLua-таблицей - это синхронные или асинхронные сообщения?
Саппорт, можете просветить?
Почему скрипты в QUIK выполняются дольше
 
Хотя есть от main и польза: перенос сложных расчётов в main при одновременной работе двух и более таких скриптов (при достаточном количестве процессоров и условии, что колбеки не будут мешать расчётам).
Почему скрипты в QUIK выполняются дольше
 
Добавим блокировку для "монопольного" вычисления в колбеке:
Код
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 выполняются дольше
 
Немного модифицируем первоначальный скрипт:
Код
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
Выводы делайте сами.
Выделять объём на тиковом графике цветом в зависимости от направления сделки
 
Цитата
Игорь М написал:
Если искать по идентификатору сделки порядковый номер в таблице
Сравнение в скорости линейного поиска с SearchItems:
Скрытый текст
Цитата
Искомый элемент в начале таблицы:
linSearch: 0.660
SearchItems: 0.495
Цитата
Искомый элемент в конце таблицы:
linSearch: 18.437
SearchItems: 4.919

Бинарный поиск можно использовать только по монотонно возрастающему (или убывающему) параметру.
Выделять объём на тиковом графике цветом в зависимости от направления сделки
 
Игорь М, добрый день.
Спасибо за информацию. Но есть сомнения относительно верности результатов.
По моим исследованиям SearchItems быстрее линейного поиска даже если искомый элемент находится первым в таблице. Если же искомый элемент глубже, то SearchItems может быть быстрее в несколько раз.
Линейный поиск имеет преимущество только при поиске в обратном направлении, если искомый элемент находится ближе к концу таблицы.
Что касается бинарного поиска, то, как верно заметил Anton, в общем случае его использовать не получится.

Применительно к тиковым индикаторам тут вот какая проблема.
Ниже индикатор, показывающий время построения индикатора.
Скрытый текст

С вызовом getItem или SearchItems на каждый тик время увеличивается в 4-5 раз. И это только вызов функций, без поиска сделки.
Отладка QUIK 8.8
 
Проблема, описанная в теме [BUG] QUIK вешается при использовании DestroyTable из main, актуальна.
Не обновляется таблица при добавления цикла repeat...until
 
Код
asset=10
repeat
  asset=asset-1
until asset==7
print('total: ' .. asset)  --> total: 7
Проблема явно не цикле repeat, а в том, что когда цикл заканчивается, вы возвращаетесь к следующей итерации цикла while, где проверяете позицию
Код
local asset = getFuturesHolding("SPBFUT", "SPBFUT****","SRU0",0).totalnet
которая отличается от нужной вам, т.к., вы только отправили транзакции, надо ещё дождаться, когда сделки исполнятся, сервер соизволит обновить позицию и отправит её клиенту.
контроль исколнения многоконтрактовой заявки в quik 8.6
 
Цитата
Коля Маржин написал:
при сделке на один контракт OnTrade() может срабатывать дважды) - как это всё контролировать?
По trade_num фильтровать
контроль исколнения многоконтрактовой заявки в quik 8.6
 
flags в OnOrder подскажет, когда заявка исполнена
Выделять объём на тиковом графике цветом в зависимости от направления сделки
 
Цитата
Sergey Gorokhov написал:
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа.
Удалось рассмотреть и проанализировать?

Или добавьте параметр flags к тиковым графикам, чтобы при построении пользовательских индикаторов не лазить в таблицу "all_trades" в поисках нужной сделки - очень сильно затормаживает расчёт: сам только вызов SearchItems увеличивает время расчёта в 10 и более раз.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
 
Тогда вашу функцию
Цитата
Sergey Gorokhov написал:
узнать включена ли подписка
Но чтобы она также давала информацию получен ли параметр с момента последней подписки:
nil - подписка не включена
false - подписка включена, но параметр ещё не получен
true - подписка включена, параметр получен
Или: 0, 1, 2
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
 
Скрытый текст
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
 
Цитата
Sergey Gorokhov написал:
Вам по сути нужен способ узнать включена ли подписка.
Пример с getQuoteLevel2 показателен.
Если вы про аналог функции IsSubscribed_Level_II_Quotes, то она бесполезна, т.к. показывает, что подписка включена в то время когда, данные ещё не получены.
Но дуэт Subscribe_Level_II_Quotes и getQuoteLevel2 самодостаточен и позволяет получать только актуальные данные.
PS: Обратил внимание, что после остановки скрипта, подписка на стакан не закрывается автоматически. Надо бы исправить.

Для ParamRequest и getParamEx2 хотелось бы такой же работы.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
 
Sergey Gorokhov, сможете привести однозначный алгоритм получения параметра, который работает всегда и надёжно, и который даёт гарантированно актуальное значение, а не старые данные из кеша? И чтобы не нужно было ждать полдня, пока ожидаемый параметр поменяет своё значение.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
 
Цитата
Sergey Gorokhov написал:
Если параметр уже заказан, до запуска скрипта, то getParamEx2 и так получит "актуальные данные" без всяких ParamRequest и OnParam ждать нет нужды.
Вы поспорить или по делу? Как в скрипте узнать, что параметр уже заказан?
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
 
Цитата
Sergey Gorokhov написал:
Для понимания что заказанный параметр начал ехать нужно ждать коллбэк OnParam()
С первого сообщения пытаюсь объяснить. Если параметр уже заказан (а проверить мы это никак не можем) до запуска скрипта (в ТТТ али другим скриптом), то если брать данные только в OnParam(), придётся ждать следующего обновления параметров. А для неликвидного инструмента это может быть очень не скоро. Глядишь к концу сессий чё-нить дождёмся...
А если вызывать getParamEx2 до прихода OnParam(), то нет гарантии, что там не старьё.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
 
Цитата
Sergey Gorokhov написал:
А Вы проверьте.
От вас, признаться, не ожидал такой некомпетентности.
В 17:07 была закрыта ТТТ
В 17:17 запущен ваш скрипт на демо. Результат ниже:
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
 
Alexander Kopyatkevich, мне даже не удобно вас об этом спрашивать: полагаете ваш код покажет актуальную котировку?
А если я два часа назад добавлял параметр "BID" в ТТТ, а потом убрал его. То какую котировку мне покажет ваш код: текущую или двухчасовой давности?
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
 
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?
 
Цитата
Alexander Kopyatkevich написал:
Если речь идет исключительно об актуальности данных, то рекомендуем перед тем, как вызывать getParamEx (getParamEx2), сначала вызывать ParamRequest.Таким образом, после вызова getParamEx (getParamEx2) отобразятся только актуальные данные.
Вы уверены в том, что вы пишите?
Актуальные данные клиент покажет только после того, как они попадут с сервера на клиента. И когда это будет нам неведомо. А до тех пор getParamEx2 может показывать что угодно.
Цитата
Старатель написал:
Если getParamEx2 вернул данные, то они актуальные или старые? Может, пять часов назад их заказывали, потом подписку отменили, а данные остались в кеше.
SearchItems
 
Цитата
Старатель написал:
В таком случае хорошо иметь возможность задавать направление поиска: с начала или с конца таблицы.
Цитата
Zoya Skvorcova написал:
Старатель,добрый день.
Дополнили пожелание
Напомните, вот это, что дополнили, уже реализовали?
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
 
Начну из далека.
При заказе таблицы котировок используем
Код
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-таблицах
 
Когда баг будет исправлен?
[BUG] QUIK вешается при использовании DestroyTable из main
 
8.5-8.7
В 8.1 проверил, также наблюдается.
[BUG] QUIK вешается при использовании DestroyTable из main
 
Цитата
Старатель написал:
Чтобы посыпались события, установить соединение с сервером
В рабочем скрипте вешается без этих манипуляций, просто реже.
[BUG] QUIK вешается при использовании DestroyTable из main
 
Ошибка плавающая. Причину установить не удалось.
Но замечено, что виснет с большей вероятностью, если одновременно с DestroyTable происходит какое-то событие.
Для воспроизведения написал следующий скрипт:
Код
function main()
  ID = {}
  for i = 1, 20 do
    ID[i] = AllocTable()
    CreateWindow(ID[i])
    SetTableNotificationCallback(ID[i], function(id, event)
      if event == QTABLE_CLOSE then
        run = false
      end
    end)
  end
  run = true
  while run do sleep(1) end
  for _, id in pairs(ID) do
    DestroyTable(id)
  end
end
Использование: Запустить скрипт без подключения к серверу. Чтобы посыпались события, установить соединение с сервером, и сразу закрыть одно из окон скрипта.
Отладка QUIK 8.7
 
Цитата
Sergey Gorokhov написал:
Вторая проблема, то что в свойствах индикатора, в уровне цены, нельзя указать число с точностью превышающую точность инструмента.
Проблема касается не только уровней, но и линий и отображения последнего значения на шкале. Этот баг добавили в какой-то версии 7.x
Скрипт прекращает работу, а не должен, Скрипт прекращает работу по непонятной причине, как ее выявить?
 
Как вариант, где-то в цикле main используется return
Иван Ру, ваш вопрос звучит примерно так: "Угадайте, что в чёрном ящике"? Вряд ли кто-то сможет помочь.
Отладка QUIK 8.7
 
Цитата
_sk_ написал:
Раньше терминал всё преобразовывал в float. Теперь вообще не даёт пользователю ввести дробное число, если инициализация была целым.
Попробуйте в Settings указать именно double:
Код
Settings = 
{
   Name  =   "*Индикатор",
   K  =   2.0,
   line  = 
   {
      { Name  =   "Line"}
   }
} 
Отладка QUIK 8.7
 
Цитата
Sergey Gorokhov написал:
Если на инструменте точность цены не позволяет наличие дробных значений то форма ввода цены уровней действительно не даст указать дробную цену, и собственно это не является багом.
Точность значений индикаторов, например, таких, как VHF, не может ограничиваться точностью цены самого инструмента.
Quik 8.5 не освобождается память
 
Для коллекции, при ошибке загрузки библиотеки или модуля все раннее загруженные модули не выгружаются:
Код
require(mod1)
require(mod2)  -- Тут возникает ошибка загрузки модуля

function main()
  ...
end
Createsource и смена сессии
 
Цитата
Anton написал:
Даже и функции много, флажок в датасорце, "ответ сервера получен".
Если быть точным, то флажок в userdata, на который ссылается объект ds._DataSource. Этот флажок надо из _DataSource как-то получить, - нужна функция.
Createsource и смена сессии
 
Цитата
Anton написал:
Тогда остается что, а остается ничего, сам факт приезда (первого) пакета на клиент только. Даже и функции много, флажок в датасорце, "ответ сервера получен". В сухом остатке что тогда от арки требуется: 1) убедиться, что сервер всегда что-нибудь отвечает на подписку, есть ли данные или нет; 2) на клиенте по получении первого ответа поставить флажок в датасорце.
Тоже хороший вариант.

Скрытый текст
Createsource и смена сессии
 
Цитата
Nikolay написал:
Только вот использование этой функции будет таким же неудобным, т.к. придется писать постоянный вызов этой функции, Вы же не значете когда придет ответ. Это синхронный подход. Он плохо работает.
Наличие флага "ответ от сервера получен" не лишает вас возможности использовать колбек.
Createsource и смена сессии
 
Nikolay, не могу похвастаться уровнем работы с высокими материями, новичёк ещё. Поэтому, если позволите, взгляд со стороны, неопытного программиста.

Цитата
Nikolay написал:
Ваша фнкция DS:Чё_Есть_На_Сервере_Брокера() обращается к справочной информации, т.к. Вы просто хотите получить данные о признаке наличия данных, а не их количестве. Эта информация итак приходит вместе со всеми информационными таблицами.
Не хватает признака отсутствия данных, мы об этом.
Цитата
Nikolay написал:
Вы просто хотите получить данные о признаке наличия данных, а не их количестве.
Хотите туда количество? Да, пожалуйста, просите разработчиков. Как будете использовать - ваше дело.

Цитата
Nikolay написал:
Если CreateDataSource выполнился, значит информация есть в локальном кеше. Как же она к нам попала, если на сервер ничего нет.
Конечно, информация есть, как минимум список классов, но не обязательно график.
Чтоб вы понимали, как это работает (на примере графика цены и объёма):
Когда вы вызываете CreateDataSource, она проверяет валидность класса, и, в случае успеха, тут же выплёвывает вам data_source. Причём, возможны несколько вариантов:
1) Если график уже открыт, то CreateDataSource сразу выдаст вам заполненный data_source.
Если график не открыт, то:
2) Если клиент оффлайн и находит в кеше нужный бинарник, то в data_source будут свечи из этого бинарника.
3) Если клиент оффлайн и графика в кеше нет, то data_source будет пустой (Size = 0).
4) Если клиент онлайн, то data_source будет пустой (Size = 0) до тех пор, пока не получит хоть одну свечу.

Цитата
Nikolay написал:
Если их 0, то что? Не было торгов?
Может, не было, а может, было, не узнаешь, пока не пройдёт хоть одна сделка. См. выше, четвёртый пункт.

Цитата
Nikolay написал:
тип ошибки: 404 или 204 и д.р.. А я как раз хотел бы видеть коды ответа сервера. А не просто ничего нет на сервере.
Здравая мысль, просите разработчиков. Но, насколько мне известно, до недавнего времени у сервера отсутствовала функция мониторинга "почему сломался график." Не знаю, может, появилось что-то.

Цитата
Nikolay написал:
Если сервер ничего не прислал, то это не значит, что там ничего нет - это значит, что идет процесс передачи, обработка запроса.
А кто с этим спорит? Мы пока не знаем, что "там" есть.
Страницы: 1 2 3 4 5 6 7 8 9 10 11 ... 31 След.
Наверх