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

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

Страницы: Пред. 1 ... 11 12 13 14 15 16 17 18 19 20 21 ... 46 След.
[BUG] Не рассчитывается максимальное возможное количество лотов в заявке
 
QUIK Junior 8.8.1.5
Скрытый текст
Надо делать так, как надо. А как не надо - делать не надо.
Quik 8.5.1.18 вылетает без видимых причин.
 
Цитата
Юрий написал:
периодически вылетает во время торговли без видимых ошибок и причин. То есть вот он работает и в следующий момент он уже не запущен вообще в системе.

QUIK 8.8.1.5
Вылеты продолжаются
Надо делать так, как надо. А как не надо - делать не надо.
Получение данных из таблиц при автостарте
 
Цитата
Старатель написал:
до подключения к серверу
Цитата
Старатель написал:
при первичном старте скрипт берёт данные из кэша.
Надо делать так, как надо. А как не надо - делать не надо.
Получение данных из таблиц при автостарте
 
Добрый день.

Есть скрипт, который стартует автоматически при запуске 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) на клиенте по получении первого ответа поставить флажок в датасорце.
Тоже хороший вариант.

Скрытый текст
Надо делать так, как надо. А как не надо - делать не надо.
Страницы: Пред. 1 ... 11 12 13 14 15 16 17 18 19 20 21 ... 46 След.
Наверх