-- ©2020 by Evgeny Shibaev -- Таблица, отображающая в процентах рост(падение) инструмента финансового рынка за определенное количество дней -- Какие инструменты(тикеры) отслеживаем. Таблица пар тикер - площадка tickers = {SiU0 = "SPBFUT", RIU0 = "SPBFUT", BRN0 = "SPBFUT", GZU0 = "SPBFUT", SRU0 = "SPBFUT", GAZP = "TQBR", SBER = "TQBR", YNDX = "TQBR", GMKN = "TQBR", MGNT = "TQBR", SU26207RMFS9 = "TQOB"} -- За ппоследние n-дней days_before = {1, 2, 3, 5, 10, 30, 44, 67, 90} -- эквивалентно "вчера", "позавчера", 3-дня назад, 7 и 30 торговых сессий назад. sources = {} -- Список источников данных по количеству тикеров rows = {} -- Список строк в таблице по количеству тикеров screener = AllocTable() -- Указатель на саму таблицу stopped = false -- Остановка скрипта -- Функция вызывается перед вызовом main function OnInit(path) -- "Ticker"- название первого столбца в таблице AddColumn(screener, 0, "Ticker", true, QTABLE_STRING_TYPE, 15) -- Названия остальных столбцов в таблице по количеству days_before for column, days in ipairs(days_before) do AddColumn(screener, days, days.." day(s)", true, QTABLE_STRING_TYPE, 11) end CreateWindow(screener) -- Даем название таблице SetWindowCaption(screener, "Percent change for last days") for ticker, board in pairs(tickers) do --Для каждого тикера создаем источник данных - "дневки" sources[ticker] = CreateDataSource(board, ticker, INTERVAL_D1) --Устанавливаем коллбэк функцию для каждого тикера. Она вызывается при изменении цены тикера. "А что, так можно было?" sources[ticker]:SetUpdateCallback(function(index) InvalidateCallback(index, ticker) end) --Для каждого тикера определяем строку в таблице и запоминаем ее в rows rows[ticker] = InsertRow(screener, -1) --В первом столбце каждой строки будет имя тикера SetCell(screener, rows[ticker], 0, ticker) end end -- Коллбэк функция вызывается при изменении значения текущей цены тикера. Обновляет строку тикера в таблице сразу, как происходит изменение. function InvalidateCallback(index, ticker) for column, days in ipairs(days_before) do -- Определяем процентр изменения цены тикера за days-дней percent = Change(ticker, days) -- Выводим в соответствующую ячейку таблицы процентр изменения SetCell(screener, rows[ticker], days, string.format("%.2f", percent).."%") -- Подкрашиваем ячейку соответственно росту(падению) и величины роста(падения) SetColor(screener, rows[ticker], days, BCellColor(percent), FCellColor(percent), BCellColor(percent), FCellColor(percent)) end end --Функция определяет на сколько процентов выросла или упала бумага относительно N-дней назад function Change(ticker, days_before) len = sources[ticker]:Size() --Сколько всего "дневных" свечей в источнике данных конкретного тикера --Возвращаем рост(падение) в процентах текущей цены от цены закрытия days_before-торговых сессий назад return (sources[ticker]:C(len) - sources[ticker]:C(len - days_before)) / sources[ticker]:C(len - days_before) * 100 end -- Цвет текста в ячейке. Если рост - то цвет "зеленый", падение - "красный" function FCellColor(change) if change > 0 then return RGB(0,128,0) else return RGB(158,0,0) end end -- Маленькая "тепловая карта". Делает фон ячейки более интенсивным, взависимости от величины роста(падения) function BCellColor(change) bright = math.floor(255 - math.min(math.abs(change*10), 110),1) if change > 0 then return RGB(bright,255,bright) else return RGB(255,bright,bright) end end -- Функция вызывается перед остановкой скрипта function OnStop(signal) stopped = true end -- Функция вызывается перед закрытием квика function OnClose() stopped = true end; -- Основная функция выполнения скрипта function main() while not stopped do sleep(1) end end
Ииии Евгений врывается в топ самых полезных авторов Смарт-лаба))
Скринер штука полезная для некоторых стилей торговли.
«Как я обещал — пользователь Смартлаба Weddy получает КО ДНЮ РОЖДЕНИЯ код бесплатно» )))
Ну а если серьезно, то большое спасибо за Ваш труд и помощь!!!
Ну а если попытаться понаглеть, то хотел бы обратить внимание на нюанс из моего ТЗ :):
Т.е. источником моей мечты о сканере было то обстоятельство, что большинство он-лайн сканеров показывает изменение цены за те, или иные периоды по отношению к цене закрытия. И как-то не попадались сканеры, где изменение отражалось бы по отношению к high/low цены дня точки отсчета.
Идея здесь простая. Вот 19.01.2020 был хай индекса ММВБ. Хотелось бы задать эту дату и увидеть в таблице изменение текущих цен инструментов по отношению к их хаям в заданный день. Посмотреть в сравнении кто на сколько больше/меньше упал.
И наоборот. 15.03.2020 был лоу по индексу ММВБ. Посмотреть, сравнить кто на сколько отскочил со своих лоев на ту дату.
Наверно для анализа акций удобней было бы задавать для таблицы вообще лишь класс TQBR, без вбивания кодов 260+ инструментов. Хотя у выборки с определенным набором инструментов есть своя ценность, при сужении акцента отслеживания.
заменить можно указанием собственного ориентира, а внутредневной-недельный-квартальный саб бы подхватывался
это к выражению «самые дорогие ошибки — в неверной концепции», в данном случае, это выразилось в непрозрачности алгоритма что требуется — производитель реализовал алгоритм не тот, что представлял потребитель
верна суть алгоритма? — отображение текущего отклонения от заданной цены, для удобства в окно сообщения отклонение от дневных\месячных\годовых экстремумов
принимает на вход дату
выводит максимальные цены с отношением к текущей цене в виде таблицы нескольких инструментов, так?
По поводу хай-лоу — мне главное как вы хотите видеть это представленное в таблице. Если задавать даты по столбцам, то часто будет что хай Газпрома по дате не приходится на хай Сбербанка по дате.
Поэтому предлагаю вариант — вы задаете как сейчас период в количестве торговых сессий, скрипт вычисляет хай-лоу за этот период, а затем «расстояние в процентах» текущей цены от этих хай-лоу. Шпильки (выбросы цены) также будут учтены в этом случае. давайте на неделе как время будет — подкорректирую.
Насчет вбивания кодов — вы все равно будете «вбивать» имя тикера, скопируйте просто 260+ строк с уже готовым кодом и всё.
Все же не понял мысль здесь:
1) Если я задам days_before = {12}, то скрипт вычислит хай-лоу за весь период 12 дней, или в день 12 дней назад? Это разные варианты, каждый имеет свою ценность. Если можно задать переключатель, то здорово. А так я имел в виду вариант хай/лоу в 12-й день от текущего. чтоб можно было увидеть разницу с определенным днем (как писал например, с днем хаев индексов, див.отсечек, других ключевых дат).
2) Как понимаю надо переключатель чтоб задать хай или лоу определять.
3) Хорошо бы выводил в столбец определенное значение хай/лоу, чтоб легко проверить то ли сделал. По крайней мере на начальном тестовом этапе.
4) Вычислить кол-во торговых дней до желаемой даты отсчета конечно можно. Хотя вбить конкретную дату было бы быстрее и безошибочнее.
Поясните еще это:
— т.е луа не позволяет после указания кода класса самой заполнить таблицу имеющимися на бирже тикерами и надо именно указать каждый тикер?
— откуда «скопируйте просто 260+ строк »? Мне пока пришло в голову лишь вывести через DDE в эксель таблицу текущих торгов, там уже удалить лишние столбцы, и формулами попытаться связать в требуемый синтаксис MGNT = «TQBR»,
На счет кода класса, вы получите несколько тысяч тикеров одного кода класса — если вы их все отслеживаете — поздравляю, вы обеспеченный человек — в этом случае можно дать указание секретарше вбить напротив тикера "=" и код класса вручную ))) без обид....
Ну я же не об этом писал ранее: Т.е., я задал дату, это в примере 19.01.2020. И задал, что надо определять хай. Скрипт определил дневной хай цены по инструменту который был именно на этот день, а не в течение месяцев после. Это например 224,5 руб. В условные 16:27 сегодняшних торгов цена по инструменту 194,56руб. Скрипт выводит относительное изменение между этими 2-мя ценами.
Если же для даты 19.01.2020 задано определять лоу, а не хай, то соответственно скрипт отображает изменение цены от лоу дня 19.01.2020 до текущих 194,56руб.
Не знаю насколько сложен переключатель задания определять хай или лоу нужного дня. Возможно проще скрипту определить и хай и лоу заданного дня (19.01.2020 в примере) и вывести в строке оба относительного показателя «хай 19.01.2020 к текущей цене» и «лоу 19.01.2020 к текущей цене»
я исходил из того, что на ММВБ всего 260+ акций, а не несколько тысяч. А так, скринер как раз для того и нужен, чтобы из большой массы выловить те инструменты, которые внимательнее рассмотреть, отслеживать. И как раз избежать ситуации, чтобы отслеживать тысячи.
АААА!
Я памятник себе воздвиг нерукотворный
К нему не зарастет народная тропа?
Боюсь обидеть, извиняюсь, если что...
Какое отношение сборник древнееврейских мифов имеет к народностям, проживающим исторически в лицемерии?
тренируешься ожидая из вне благодарность?
Да неее...
У благодарности очень низкие котировки, а фундаментал вообще грустный...
Пятничное…
Иисус вернул зрение 12 слепым, и только трое сказали спасибо.. ..
Это он Вам сам сказал?
Вы по аккуратней...
Расширенное сознание может назад не вернутся…
Логичнее же все то же самое замутить в рамках коммерческого проекта? Напуркуа благотворительность? При чем это массово — полезного халявного кода — полинета.
Если как оставить о себе память — более менее понятно — компенсация навязанной манипуляции. Если с другой целью — не понятно…
У меня много что, много от чего, выделяется ...
Но два безвозвратных ресурса: время и здоровье — обычно трачу с личной пользой…
Эх помница на автолиспе ваял я код под автокад.
Бабули впрочем были против («био-копир наш был не рад»)
Одно и то же рисовали толпой, годами — это скука!
Поставил плоттер (струйный правда), а мне сказали, что я — сука. :)
И вот когда стал выбор между мультичартс и тс лабом, я выбрал первый как только прочитал, что его EasyLanguage — это Pascal.
Выбор возможно иррациональный, уж как то долго я его осваиваю, куча граблей. Хочется верить что в тс лабе все проще. Но все равно какой это кайф было вспомнить первую любовь :)
function Change(ticker, days_before)
len = sources[ticker]:Size() --Сколько всего «дневных» свечей в источнике данных конкретного тикера
--Возвращаем рост(падение) в процентах текущего объема от объема закрытия days_before-торговых сессий назад
return (sources[ticker]:V(len) — sources[ticker]:V(len — days_before)) / sources[ticker]:V(len — days_before) * 100
end
Здесь только нюанс — в таком варианте объем имеет смысл смотреть в конце дня, т.к. особенно вначале, он будет показывать отрицательное изменение — или я не так понял ТЗ?)))
А вообще по использованию — не было времени проверить, но нужно учитывать следующее — у фьючерсов и, например акций «время жизни» разное, фьючерс может существовать полгода — год, а акция 10 лет и более.
Поэтому корректно было бы сделать дубликат кода скрипта, и в один скрипт поместить список акций, а в другой список фьючей. Получатся две таблицы, тогда для акций можно будет задавать большее количество дней отдельно от фьючей.
function Change(ticker, days_before)
Дата в названии столбцов — это финальная часть ТЗ Weddy, постараюсь в течение недели сделать)))len = sources[ticker]:Size() --Сколько всего «дневных» свечей в источнике данных конкретного тикера
--Возвращаем рост(падение) в процентах текущей цены от цены закрытия days_before-торговых сессий назад
return (sources[ticker]:V(len) — sources[ticker]:V(len — days_before)) / sources[ticker]:V(len — days_before) * 100
end
sources[ticker] = CreateDataSource(board, ticker, INTERVAL_D1, «NUMCONTRACTS»). В этом случае в качестве параметра будет количество открытых позиций. Если не получится, я сам попробую на реальных торгах завтра — отпишу.