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

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

Страницы: 1
Где к терминалу QUIK привязана гиря?, Проблема с крайней заторможенностью одного из моих двух терминалов.
 
Уважаемые QUIK clients support, эта тема создана не шутки ради, а помощи для. Не соизволите ли отреагировать?
Где к терминалу QUIK привязана гиря?, Проблема с крайней заторможенностью одного из моих двух терминалов.
 

У меня одновременно запущены два терминала QUIK 9.2.3.15. Брокер БКС. Количество графиков в обоих примерно одинаковое. Из индикаторов только объем используется.

Один терминал подключен к счету с единой денежной позицией, другой – только FORTS. Тот, который только FORTS – работает хорошо по крайней мере в нормальных условиях, когда нет очень сильных движений на рынке, а когда сильные движения есть – вполне удовлетворительно.

А вот тот, который с единой денежной позицией – очень напрягает в части отзывчивости интерфейса пользователя. В зависимости от везения начинает тормозить либо сразу с утра либо через часок-другой. Торможение заключается в появлении указателя мыши, сигнализирующего занятость приложения, сам терминал при этом, естественно, никак не реагирует на мои попытки дать какие-либо команды. Один "сеанс" такого торможение может длиться 10-120 секунд. И происходит очень часто – можно сказать постоянно. Обычно раз-два в минуту подвисает секунд на 10-20. Это очень много. Обращался в поддержку брокера, там предлагали для решения проблемы перезаказывать все данные со сменой соединения – как оказалось, точно такая же лотерея, как и при первом запуске с утра – либо работает, либо нет. Я уже не говорю, что соединение устанавливается минут 5 (когда пишу эти строки – зафиксировал рекорд – 10 минут и соединение так и не установлено).

Ни одной из вышеперечисленных проблем на терминале, подключенном к счёту FORTS, не наблюдается.

Единственная проблема, которой грешат оба моих терминала - – отставание данных графика на время до трёх минут, причём терминал, подключенный к «только FORTS» страдает этим редко.

Иногда на время помогает переподключиться на другое соединение. Но помогает далеко не всегда, причем корреляции между успехом и выполненным перед переподключением перезаказом данных я не уловил. В результате за торговый день не менее часа уходит только на упражнения со сменой соединения и переподключением.

Как-то ради эксперимента скопировал папку беспроблемного терминала, подключенного к FORTS и настроил его для работы со счетом с единой денежной позицией – и о, чудо – такие же тормоза, как и ранее.

Я не в Москве, интернет не идеальный, что правда, ничуть не мешает отлично работать терминалу, подключенному к FORTS и одновременно смотреть, например, HD ролик в YouTube.

Список обновляемых инструментов и параметров формируется «умным» заказом. Настроил получение только необходимых параметров котировок только для необходимых инструментов – результат не изменился. Журналом обезличенных сделок не пользуюсь. Для сохранения получаемых инструментов и параметров установлен флажок «Только данные, отражающие текущее состояние». Обновление текущих значений установлено по запросу, 1 раз в 15 секунд. Компьютер мощный, памяти много, накопитель шустрый.

Документы «FAQ: Возможные проблемы с производительностью и рекомендации по их устранению» и «FAQ: Оптимизация производительности клиентского места QUIK», прочитал, *.log файлы чищу, но это не помогает.

Прошу объяснить, где к терминалу QUIK может быть привязана гиря и конструктивно помочь с решением проблемы.

Вкладки, Возможность откреплять вкладки
 
Цитата
Egor Zaytsev написал:
Здравствуйте!

Ваше пожелание зарегистрировано.  Мы постараемся рассмотреть его и  сообщить Вам результаты анализа. Впоследствии, по результатам анализа,  будет приниматься решение о реализации пожелания в будущих версиях ПО.

Сообщите, пожалуйста, результаты анализа и о принятом решении по данному вопросу.
повторный Init() без OnDestroy() в индикаторе, При смене инструмента графика в Lua индикаторе перечитывается файл без предварительного срабатывания OnDestroy()
 
Цитата
Sergey Hlynovskii написал:
 Здравствуйте  BlaZed ,
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Какие новости по фиксу бага утечки ресурсов в скрипте индикатора? Вы же как баг это зарегистрировали, не так ли? Рука не поднимается (язык не поворачивается) назвать просьбу исправить такую грубую функциональность "пожеланием".
Замена стоп ордера
 
Прошу прощения, запутался в попытке сделать уточнение к своему сообщению #11 и случайно отправил сообщение #12.
Цитата
... случаются, при этом НЕ так уж внезапно и хороший робот уже в нужном направлении должен позу держать либо быть вне рынка. Более того, я обязательно возьму (вашу точку зрения) на рассмотрение и вооружение!
Вот так должно было быть)
PS. в этом форуме редактирование и удаление сообщений доступно?
Замена стоп ордера
 
Цитата
Анатолий написал:
Владимир, Хорошо, вы молодец! ::  У меня нет принципиальных возражений против вашей точки зрения, тем более что глубокие движения без отскока от силы раз в квартал случаются, при этом так уж внезапно и хороший робот уже в нужном направлении должен позу держать либо быть вне рынка. Более того, я обязательно возьму (вашу точку зрения) на рассмотрение и вооружениеПоправка: не т
Замена стоп ордера
 
Владимир, Хорошо, вы молодец! :smile:  У меня нет принципиальных возражений против вашей точки зрения, тем более что глубокие движения без отскока от силы раз в квартал случаются, при этом так уж внезапно и хороший робот уже в нужном направлении должен позу держать либо быть вне рынка. Более того, я обязательно возьму (вашу точку зрения) на рассмотрение и вооружение!
Замена стоп ордера
 
Цитата
Владимир написал:
Анатолий, Да я, честно говоря, вообще не понимаю, зачем нужны стоп-лоссы - здесь же скрипт, и он вроде как постоянно работает. Ну, разве что связь вдруг разорвётся, и именно в этот момент на рынке произойдёт что-то непотребное. Не говоря уже про тейк-профиты. Ну, поставили мы там что-то по своим доморощенным представлениям о поведении рынка, а как он там себя на самом деле поведёт - одному богу известно (да и то вряд ли). Ну, сработает там этот "профит", а рынок, мож, только начал разгоняться, и ещё на 5-10-20% взлетит. Или чирикнет по нашему стоп-лоссу, оставит нас без акций и повернёт вверх. У меня никаких лоссов с профитами вообще нет. Вернее, лосс-то есть, но он динамический - теоретически может двигаться каждые полторы секунды, но двигаться У МЕНЯ. А заявку, когда скрипт посчитает нужным подать, он подаёт всегда по LAST или даже по BID или OFFER. Кстати, заодно снимаются все проблемы с шагом цены - какая бы она ни была, у любого из этих трёх параметров с шагов всё в порядке.
Именно на случай разрыва связи. И при редко быстрых движениях цены есть надежда, что на стороне сервера брокера быстрее стоп отработает, чем через клиентский терминал. Ну а по поводу использования того или иного подхода в стоп лоссах - это всё вопрос личных предпочтений ну и бэктестов, разумеется.
Замена стоп ордера
 
Цитата
Владимир написал:
Анатолий, Ну и правильно сделают, если не реализуют. В чём здесь удобство? Ну, напишите свою функцию замены стоп-ордера, если вам так "гораздо удобнее", которая будет передвигать его через "снять/выставить" - минут 5 на это потратите. Насколько я помню, это называется "инкапсуляция". ::  
Спасибо, кэп, уже написал. Удобство замены стоп-заявки - в атомарности операции. Соглашусь разве что с тем, что приоритет введения данной функциональности невысок.
Замена стоп ордера
 
Присоединяюсь к пожеланию, но не верю, что реализуется в течении ближайших 10 лет.
Снятие заявки, server check failed
 
Цитата
Andrey Bezrukov написал:
Здравствуйте, Сергей.

Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Здравствуйте. Какова судьба реализации программного доступа к таблице транзакций из LUA?
повторный Init() без OnDestroy() в индикаторе, При смене инструмента графика в Lua индикаторе перечитывается файл без предварительного срабатывания OnDestroy()
 
Цитата
Egor Zaytsev написал:
Добрый день.

К сожалению, на данный момент ошибка действительна не исправлена.
Будьте любезны, заведите/освежите "тикет", пожалуйста)
Вставить вызов пользовательской функции OnDestroy и/или закрыть Lua контекст пользовательского скрипта (для вызова финализаторов) при смене инструмента графика, как это делается при удалении индикатора.
повторный Init() без OnDestroy() в индикаторе, При смене инструмента графика в Lua индикаторе перечитывается файл без предварительного срабатывания OnDestroy()
 
Эти контексты (контексты Lua от предыдущих инструментов на графике) - тупо живые! Я сохранял lua_State* от них и проверял все в OnInit - в этих контекстах тестовые глобальные переменные и их значения сохранены. И финализаторы не вызываются даже при закрытии терминала. Утечка ресурсов в нетривиальном пользовательском индикаторе неизбежна.
повторный Init() без OnDestroy() в индикаторе, При смене инструмента графика в Lua индикаторе перечитывается файл без предварительного срабатывания OnDestroy()
 
Проблема отсутствия вызова "OnDestroy" при смене инструмента до сих пор актуальна (QUIK 8.13.1.6). Не вызываются даже финализаторы объектов Lua, созданных в контексте предыдущего инструмента. Годы идут, когда ожидать решения проблемы?)
Доступ к Settings.line из кода индикатора, Пропадает доступ к массиву line структуры Settings в индикаторе после добавления индикатора на график и последующего изменения какого-либо параметра.
 
Цитата
Roman Azarov написал:
Анатолий, добрый день!

Описанное Вами поведение корректно.
Обратно в скрипт, после изменений, параметры линий не передаются
В документации ничего не сказано о том, что "Обратно в скрипт, после изменений, параметры линий не передаются". Очевидно предположение, что вся структура Settings доступно всегда из скрипта. Вопрос - зачем удалять line?

Цитата
Roman Azarov написал:
Анатолий, добрый день!

Можем предложить зарегистрировать пожелание на доработку данного функционала. Регистрируем?
Будьте так любезны, зарегистрируйте.
Доступ к Settings.line из кода индикатора, Пропадает доступ к массиву line структуры Settings в индикаторе после добавления индикатора на график и последующего изменения какого-либо параметра.
 
Обнаружил, что после добавления индикатора на график и последующего изменения какого-либо параметра данного индикатора в коде индикатора обращение к Settings.line даёт nil, при этом кастомные параметры индикатора, объявленные в "корне" структуры Settings остаются доступными. QUIK 8.13.0.106. Немного поискав по форуму подобной проблемы не обнаружил - прошу извинить, если плохо искал.

Код:
Скрытый текст

Инструкция по воспроизведению проблемы:
1) Добавить индикатор на график в любую область и закрыть модальное окно свойств окна графика, если применимо.
2) Наблюдать поочередно сообщения "Init: line is NOT nil" и "OnCalculate(index==1): line is NOT nil", т.е. доступ к line есть.
3) Открыть свойства этого графика, перейти на параметры индикатора и изменить какой-либо кастомный параметр в Settings, например Param2, кликнуть "OK".
4) Наблюдать поочерёдно сообщения "OnChangeSettings: line is nil" и "OnCalculate(index==1): line is nil", т.е. доступа к line нет.

Доступ к line необходим, чтобы синхронизировать цвета текста меток с цветами линий.
Прошу определить, является ли вышеописанное поведение в виде получения nil по ссылке Settings.line ошибкой в QUIK, моей ошибкой либо моими завышенными ожиданиями.
Заранее спасибо.
Автологин
 
Цитата
Роман написал:
Скрипт говорит, что работает, но соединение автоматом не восстанавливает при обрыве или ручном отключении.

Здесь приведен пример, как программно из LUA скрипта вызвать появления окна "Идентификация пользователя", которое в свою очередь заполнит вышеупомянутый скрипт автологина.
Сообщения QTABLE_LBUTTONUP и QTABLE_RBUTTONUP, Расширение информационных функций сообщений
 
Ситуация:
В моей библиотеке используются таблицы рабочего стола QUIK и, соответственно, обрабатываются оконные сообщения. Когда пользователь нажимает, например, левую кнопку мыши над ячейкой одной из таких таблиц и затем, не отпуская кнопки, переносит курсор мыши на другую пользовательскую таблицу - сообщение QTABLE_LBUTTONUP приходит с tid таблицы, над которой кнопка была отпущена. Но если пользователь отпустил кнопку не над пользовательской таблицей, а над любым другим произвольным местом окна QUIK или над свободном от ячеек месте пользовательской таблицы - никакое сообщение не приходит и это не позволяет создать полноценную обработку событий от мыши для реализации достаточно вменяемого и функционального "псевдографического"  пользовательского интерфейса.

Предложения:
1) Расширить информационные функции сообщений QTABLE_LBUTTONUP и QTABLE_RBUTTONUP таким образом, что в случае, если отпускание кнопки, нажатой над пользовательской таблицей, происходит не над пользовательской таблицей, то сообщение QTABLE_LBUTTONUP (или QTABLE_RBUTTONUP соответственно) приходит в обработчик, зарегистрированный для таблицы, над которой кнопка была нажата, но с tid = 0.
2) Расширить информационные функции сообщений QTABLE_LBUTTONUP и QTABLE_RBUTTONUP таким образом, что в случае, если отпускание кнопки, нажатой над пользовательской таблицей, происходит над (любой) пользовательской таблицей в свободном от ячеек пространстве, то сообщение QTABLE_LBUTTONUP (или QTABLE_RBUTTONUP соответственно) приходит в обработчик, зарегистрированный для таблицы, над которой кнопка отпущена с tid, равным её tid и c par1==nil и par2==nil. nil - это как вариант, можно взять любую константу на ваше усмотрение.
Вкладки, Возможность откреплять вкладки
 
Цитата
Egor Zaytsev написал:
Цитата
Ильдар Хажин написал:
Здравствуйте! Скажите пож-та, как продвигается реализация функции о выносе вкладок на другие мониторы?
Многим эта функция очень нужна, просьба рассмотреть этот вопрос в ближайшее время. Спасибо
Добрый день.
К сожалению, пока пока информации по данному пожеланию нет. О сроках реализации также подсказать не можем. Следите за обновлениями.
Присоединяюсь к пожеланию реализации возможности открепления целой вкладки и переноса её на другой монитор. При этом хотелось бы, чтобы монитор, на который перенесена вкладка запоминался и при следующем запуске в случае наличия данного монитора в системе - на него же вынесенная вкладка и восстанавливалась. Растаскивать по одному окну по 6 мониторам - ну это смех просто.
Поиск по тикеру / коду бумаги при создании графика
 
Пожелание по-прежнему более, чем актуально и главное - реализовать-то его не сложно.
Цитата
Stanislav Tvorogov написал:
Цитата
sandyman пишет:
Хотелось бы чтобы в меню создания нового графика и меню замены инструмента на существующем графике была реализована возможность поиска не только по наименованию инструмента, но и по его тикеру (коду бумаги).
Мы рассмотрели Ваше пожелание. По итогам его анализа сообщаем Вам, что реализация пожелания признана потенциально целесообразной. Если по результатам дальнейшего анализа, включающего юридические аспекты, анализ на непротиворечивость с общей политикой компании, никаких возражений не возникнет, мы постараемся включить Ваше пожелание в план доработок при выпуске одной из следующих версий нашего ПО.
недокументированные события QTABLE при нажатии мышки
 
Цитата
Zoya Skvorcova написал:
Sergey Denegin,      Добрый день,
   
    Документация будет дополнена в одной из очередных версий программы.
   
    Приносим извинения за причиненные неудобства.
Прошло 3 года. QTABLE_NEED_REFILL и QTABLE_CONTEXTMENU в документации не появились.
Расширение интерфейса QLUA, Пользовательские пункты контекстного меню таблиц, функция открытия окна заявки с заранее заданными параметрами
 
Конечно, подобный функционал можно реализовать с помощью пользовательских таблиц, но для этого такой огород приходится городить))
Расширение интерфейса QLUA, Пользовательские пункты контекстного меню таблиц, функция открытия окна заявки с заранее заданными параметрами
 
Прошу обратить внимание, что эти дополнения в интерфейс QLUA позволят с лёгкостью реализовать в скрипте QLUA ранее многократно и в разных формулировках запрашиваемую функцию "автоматическое выставление стоп лосса и тейк профита с заранее заданными параметрами при создании заявки". Также будет, например, легко реализуема такая плюшка, как групповое изменение заявок - отмена, изменение (например, сдвиг) лимитных и стоп цен, коррекция параметров отступа и защитного спреда, изменение параметров рыночной цены, замена инструмента (например с TOD на TOM).
Вообще, интерфейс QLUA крайне беден в плане наличия средств интерактивного взаимодействия с пользователем. Да, я понимаю, что всё можно делать через файловый ввод-вывод: мониторить новые команды, считывать их и исполнять, но это не улучшает удобство, а главное - быстроту использования.

Поэтому осмелюсь попросить ещё одну функцию взаимодействия скрипта QLUA с пользователем:
Возможность создания немодальных аналогов функции MessageBox из Win32 API. Модальные окошки не подойдут, так как могут потеряться и повесить какой-нибудь поток. Чтобы потерянные окна с запросами из скрипта несложно было найти как интерактивно, так и программно - предлагаю ввести новый тип таблиц - "Запросы из скрипта". Доступ для чтения к ней из LUA предлагаю осуществить с помощью getItem() и других функций из этой группы. Должна быть возможность интерактивно открыть необработанный ранее по каким-то причинам пользователем запрос, отправленный из скрипта и сохранённый в данной таблице. Также должна быть возможность программного снятие переставшего быть актуальным запроса, отправленного ранее из скрипта. Как вариант, можно предусмотреть время действия для каждого из запросов пользователя. Из данного описания запрошенной функциональности следует, что должна быть применена асинхронная, событийно-ориентированная модель обработки ответов пользователя. Возможно, следует ввести дополнительный callback типа OnUserAnswer(request_id, answer).

Примерные прототипы функций:
Код
registerUserAnswerCallback(FUNCTION user_answer_callback)
unregisterUserAnswerCallback()
OnUserAnswer(NUMBER request_id, STRING answer)
NUMBER MessageBoxNonModal(STRING message_str, TABLE options, NUMBER icon_code, NUMBER timeout_in_seconds) -- возвращает request_id
CancelMessageBox(NUMBER request_id)

TABLE options - таблица, содержащая набор пар <текстовое представление опции> и <идентификатор ответа>, например:
Код
options =
{
    {"Да", 1},
    {"Нет", 0},
    {"Не понял", -1}
}

Надписи на кнопках формируются из текстовое представления опции, в качестве поля answer  в callback передается идентификатор ответа.

Разумеется, при остановке скрипта по любым причинам все MessageBox, с ним связанные - закрываются, а следы в таблице "висящих" запросов скрипта (pending requests) - подчищаются.

Спасибо за внимание ;-)
Расширение интерфейса QLUA, Пользовательские пункты контекстного меню таблиц, функция открытия окна заявки с заранее заданными параметрами
 
Код коряво вставился...
Дублирую здесь
Код
openNewOrderWindow({
    ["CLIENT_CODE"]="777777",
    ["ACCOUNT"]="MB0007777777",
    ["EXECUTION_CONDITION"]="PUT_IN_QUEUE"
    ["TRANS_ID"]="777777"
    ["CLASSCODE"]="CETS"
    ["SECCODE"]="USD000UTSTOM"
    ["ACTION"]="NEW_ORDER"
    ["OPERATION"]="B"
    ["TYPE"]="L"
    ["PRICE"]="63.3000"
    ["QUANTITY"]="12"})

Код
registerUserMenuItem("quotes", "Создать заявку и стоп заявку", USER_MAKE_ORDER_AND_STOP_ORDER, UserMenuItemCallback)

function UserMenuItemCallback(table_class, menu_item_id, table_line)
    if (table_class == "quotes") then
        if (menu_item_id == USER_MAKE_ORDER_AND_STOP_ORDER) then
            --подготовить данные для транзакций
        elseif (menu_menu_item_id == USER_ANOTHER_FUNCTION) then
            --сделать ещё что-нибудь полезное
        else
            message("Не реализовано")
        end
    elseif (table_class == "orders") then
        --что-то сделать на радость всем
    end
end
Расширение интерфейса QLUA, Пользовательские пункты контекстного меню таблиц, функция открытия окна заявки с заранее заданными параметрами
 

Предложения касаются дополнений к программному интерфейсу QLUA.

1)

Реализовать функцию, создающую окно ввода новых заявок. В функцию в качестве параметра должна передаваться таблица, аналогичная таблице, передаваемой в качестве параметра в функцию sendTransaction(). Таким образом можно будет в скрипте заранее заполнить нужные параметры.

Справка по функции:

Функция предназначена для Открытия окна ввода новой заявки.

Формат вызова:

Код
NUMBER openNewOrderWindow(TABLE transaction)

Функция возвращает 1, если пользователь нажал "ОК", 0 - в ином случае

Параметр transaction - таблица, аналогичная по составу таблице, передаваемой в функцию sendTransaction().

Пример:

Код
openNewOrderWindow ({    ["CLIENT_CODE"]="777777",    ["ACCOUNT"]="MB0007777777",    ["EXECUTION_CONDITION"]="PUT_IN_QUEUE"    ["TRANS_ID"]="777777"    ["CLASSCODE"]="CETS"    ["SECCODE"]="USD000UTSTOM"    ["ACTION"]="NEW_ORDER"    ["OPERATION"]="B"    ["TYPE"]="L"    ["PRICE"]="63.3000"    ["QUANTITY"]="12"})

2)

Реализовать возможность добавления пользовательского пункта меню в контекстное меню каждого вида стандартных таблиц QUIK. При выборе пользователем этого пункта меню должен вызывается callback в пользовательском скрипте, в который должно передаваться имя класса окна (например, “quotes”, ”trades” и т.п.), идентификатор пользовательского пункта меню и таблица, содержащая значения текущей строки стандартной таблицы интерфейса QUIK. Регистрация callback пользовательского скрипта может производиться одновременно с регистрацией в QUIK параметров пункта меню.

Пример:

Где-то в коде инициализации:

Код
registerUserMenuItem("quotes", "Создать заявку и стоп заявку", USER_MAKE_ORDER_AND_STOP_ORDER, UserMenuItemCallback)

В результате вызова этой функции в контекстное меню всех таблиц котировок должен добавиться пункт меню "Создать заявку и стоп-заявку". При выборе пользователем этого пункта меню должен вызваться callback:

Код
function UserMenuItemCallback(table_class, menu_item_id, table_line)    if (table_class == "quotes") then        if (menu_item_id == USER_MAKE_ORDER_AND_STOP_ORDER) then            trans1 = PrepareOrderTransaction(table_line) --подготовить данные для заявки            trans2 = PrepareOrderTransaction(table_line) --подготовить данные для заявки            ProcessOrders({trans1, trans2})        elseif (menu_menu_item_id == USER_ANOTHER_FUNCTION) then            --сделать ещё что-нибудь полезное        else            message("Не реализовано")        end    elseif (table_class == "orders") then        --что-то сделать на радость всем    endend 

Примерные прототипы функций:

Код
NUMBER registerUserMenuItem(STRING table_class, STRING menu_item_text, NUMBER menu_item_id, FUNCTION callback)UserMenuItemCallback(STRING table_class, NUMBER menu_item_id, TABLE table_line)

Реализация этих двух пунктов позволит существенно разнообразить возможности и увеличить гибкость пользовательского интерфейса QUIK с помощью скриптов QLUA.

getParamEx
 
Цитата
Sergey Gorokhov написал:
Цитата
Владимир написал:
Извините, что не по теме, но этот топик выходит в первых строках результата Яндекса.

Я правильно понимаю, что список параметров, которые можно получить с помощью GetParamEx, до сих пор является тайной за семью печатями, и нигде-нигде официально не описан?

Не совсем так, он не является тайной.
Он есть в info.chm
-Раздел 8. Алгоритмический язык QPILE
--Функции для получения значений Таблицы текущих торгов
---Значения параметров функций

Если там какого-то параметра нет, его можно узнать выведя таблицу по DDE с установленной галкой "Формальные заголовки"
На мой взгляд совершенно не очевидно, что для того, чтобы писать скрипты на QLua необходимо сначала заглянуть в документацию по QPILE и внимательно её изучить. По крайней мере никаких ссылок такого плана на QPILE в документации на QLua не имеется.
Страницы: 1
Наверх