Уже. Вот только добавление/изменение параметров индикатора занимает достаточно много времени, в течение которого терминал оказывается в "подвешенном" состоянии.
Надо делать так, как надо. А как не надо - делать не надо.
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Sergey Gorokhov написал: Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа.
Удалось рассмотреть и проанализировать?
Или добавьте параметр flags к тиковым графикам, чтобы при построении пользовательских индикаторов не лазить в таблицу "all_trades" в поисках нужной сделки - очень сильно затормаживает расчёт: сам только вызов SearchItems увеличивает время расчёта в 10 и более раз.
Надо делать так, как надо. А как не надо - делать не надо.
Информации о результатах анализа данного пожелания пока что к сожалению нет.
Ваше пожелание по добавлению параметра flags для графиков зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Старатель написал: не лазить в таблицу "all_trades" в поисках нужной сделки - очень сильно затормаживает расчёт: сам только вызов SearchItems увеличивает время расчёта в 10 и более раз.
Старатель, здравствуйте. Увидел это ваше сообщение по поводу использования SearchItems в ТОС, а так как я раньше об этой функции не знал (как-то ускользнула от моего внимания, другие использовал), то решил её проверить и написать, что получил. Может кому-то ещё эта инфа пригодится. Сравнил её только с двумя методами поиска: линейным и бинарным. Если искать по идентификатору сделки порядковый номер в таблице, то даже линейный поиск быстрее на 30%. Бинарный быстрее в 7000 раз. Если вызывать SearchItems с параметром "trade_num", то он быстрее вызова без параметра в 10 раз (в 700 раз медленнее, чем бинарный). Не понял я замысла сей функции и области её применения. Может что-то ускользнуло от моего внимания, какой-то смысл в неё заложенный, поэтому вы у себя проверьте, вот функции, которыми проверял:
Код
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
end
local function binSearch (t, id, num_1, num_2) -- функция бинарного поиска
while num_1 <= num_2 do
local middle = num_1 + math.floor ((num_2 - num_1) * 0.5) -- середина диапазона
local t_trade_num = getItem (t, middle).trade_num -- номер сделки в таблице
if id < t_trade_num then -- сравнение идентификационных номеров
num_2 = middle
elseif id > t_trade_num then
num_1 = middle
else
return middle
end
end
end
local res = linSearch ("all_trades", 26139171939000, 0, getNumberOf ("all_trades") - 1) -- вызов
Интересное исследование. Однако есть сомнения в корректности бинарного поиска, записи в хранилище не обязаны быть строго упорядоченными по номеру. Если, например, подключены фортс и спот, там будут перемежающиеся кучки с совершенно разными диапазонами номеров, хотя в пределах кучки номера и упорядочены.
Игорь М, добрый день. Спасибо за информацию. Но есть сомнения относительно верности результатов. По моим исследованиям 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 раз. И это только вызов функций, без поиска сделки.
Надо делать так, как надо. А как не надо - делать не надо.
Игорь М написал: Если искать по идентификатору сделки порядковый номер в таблице
Сравнение в скорости линейного поиска с 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
Бинарный поиск можно использовать только по монотонно возрастающему (или убывающему) параметру.
Надо делать так, как надо. А как не надо - делать не надо.
Если нужна скорость поиска, нужно строить в памяти скрипта по колбеку onalltrade копии таблицы обезличенных сделок отдельно по каждому инструменту, правильно назначать ключ таблицы и мгновенно искать необходимую сделку уже в этой луа таблице. Переход на x64 позволяет это легко.
Старатель написал: Сравнение в скорости линейного поиска с SearchItems:
Цитата
Искомый элемент в начале таблицы: linSearch: 0.660 SearchItems: 0.495
Цитата
Искомый элемент в конце таблицы: linSearch: 18.437 SearchItems: 4.919
Да, у меня такие же пропорции по результатам. То, что линейный быстрее SearchItems, я писал для случая вызова SearchItems без параметров, а с параметром он быстрее, да. И сжирается всё вызовом getItem. Арковцы писали, что в 8-й версии была исправлена "Медленная работа функции getItem в QLUA", я сравнил, но что-то разницы с 7-й не заметил.