Да, если есть колебательный процесс, то есть соблазн представить поступательные движения тренда как фазы волны с большим периодом. А внутренние колебания (по сути шум) как гармоники. Эта идея не нова, а у же с середины 90-х заезжена вдоль и поперек. Помню как радиофизики тогда с придыханием говорили, что вот сейчас придём и научим всех как надо. Доля смысла есть в этом подходе, но только пока процесс не изменится. И сразу всё ломается, т.к. цена не обязана идти по ряду Фурье. Если бы временной ценовой ряд можно было представить аналитически, то, наверно, это уже давно бы сделали. Так что да, такой подход возможен, но тогда необходимо постоянно пересчитывать модель.
Цитата
VPM написал: Кстати у Вас есть прекрасный индикатор регрессионного анализа, выделяющий тренд 3 видов с использованием волатильности. Я его активно использую, пользуясь случаем хочу Вас попросить посмотреть его затирает текущие значения.
Странное определение тренда через частоту. Раз частота, значит колебательные движения. А если тренд, то какие тогда колебания. Тренд - это линейная зависимость.
Например ema - фильтр, где используется прошлое значение, полученное на текущем окне. Хотя да, это уже строго говоря не скользящее окно. На скользящем окне Вы каждый раз рассчитываете результат по данным этого окна, не смотря дальше. Но с другой стороны, если окно изменить, то можно получить резкий скачок в данных. Было окно 100, стало 10. Результат уже явно другой. Т.е. цель изменения окна - это изменить работу фильтра для всего сигнала. А если изменять его туда-обратно, то как такой сигнал потом интерпретировать.
В этом плане самый простой и понятный фильтр для финансовых данных - это WVAP. Есть веса от объема. Его можно даже доработать, добавив веса от позиции данных в окне выборки, снижая вес дальних индексов в окне. А просто фильтры основанные на математике из стационарных рядов - ещё надо объяснить почему это должно работать на финансовых данных.
VPM написал: И последнее, просто напомню, что обратная величина частоте, это тот самый период, который мы просто можем адаптировать, с помощь математики. А значит и фильтры применять с этими периодами каждый по назначению.
Это Вы может делать только если данные независимы. А если окно скользящее, с зависимостью, что изменяя "на лету" окно ничего хорошего ожидать не стоит.
Идея сглаживания - это борьба с выбросами. Как только Вы начинаете бороться с запаздыванием, то сразу возникает вопрос: а зачем тогда сглаживать? Тогда лучший - это просто сам график. Запаздывания нет. Ну и прежде чем браться за идею, стоит понять к чему приводит сглаживание. Это хорошо видно при преобразовании Фурье. Вот здесь очень наглядно про это https://rutube.ru/video/beeb00abb33061f14a37f54d3536a10b/
Т.е. если браться за фильтрацию сигнала, то сначала необходимо определиться для чего.
Терминал Квик не позволяет открывать (управлять) любые внутренние окна через интерфейс lua. Можно написать dll которая будет пытаться нажимать кнопки интерфейса - но такое... Метод CreateWindow - это создание окна в виде таблицы, которое можно использовать при работе скрипта. Поэтому можно создать свою таблицу и заполнять её данными стакана. Но это не будет то же самое, что внутреннее окно. Все команды и реакции тоже необходимо будет реализовать.
Цитата
ИИ говорит, что можно использовать такую функцию
Это не ИИ - а галлюцинирующая модель. Документация + собственный И - вот и всё что необходимо.
Терминал в данном случае - это просто труба, что пришло с биржи, то и показал. Сам не придумывает. Такой ответ, кстати, возможен если тип ордера вышел "исполнить или снять". Раз встречных нет, то снята.
Код ответа, конечно, мог бы быть более разнообразным, но мы уже привыкли. Также все же это больше зависит от алгоритма. Отправляя рыночный ордер не стоит ожидать, что он исполнится, как раз наоборот, стоит ожидать, что нет. Плюс не стоит отправлять рыночный ордер не проверив есть ли встречные ордера. Когда их нет - это не имеет смысла.
Также пока пакет дойдёт до биржи в стакане может стать пусто - и это нормально и надо это предусматривать. К тому же рыночный ордер - это абстракция. В ядре бирже есть только лимитные ордера по ценам внутри допустимого диапазона. Рыночный - это просто ордер по границе, чтобы встречный был с очень большой вероятностью. А вот когда встречных нет, то и выходит проблема.
tohoki написал: Существует ли какая-нибудь внятная документация, где сформулировано, что есть дата расчета, откуда она берется, по каким правилам формируется, что такое Тх и все остальное? Чтобы не бродить впотьмах, а просто понять.
Мне нужно следующее. Терминал, в нем происходят сделки. Нужно в колбеке ondepolimit в момент изменения позиции по инструменту найти ПОЛНУЮ позицию по этому инструменту без каких либо дат расчета и скажем, вывести ее не экран.
Есть ли какой нибудь разумный алгоритм, который позволит это сделать и у втб-подобного брокера, и у тех, кто уже исполнил перестройку и гласность?
В данном случае - это нововведение разработчиков терминала, впрочем, даже скорее всего менеджеров. На бирже есть понятие "Режим торгов (расчётов) Т+", и ранее limit_kind вполне повторял его. Теперь же это не так, т.к. там дата и режим - это разница текущей и даты в параметре (условно). Что уже не соответствует понятию "Режим торгов", т.к. уже отражает дату проведения расчёта. Скорее всего решения было принято для того, чтобы было видно в какую дату произойдёт расчёт, что режим торгов Т+ не давал, т.к. могут быть выходные, праздники и т.д.
Впрочем, как и ранее, алгоритм такой же - найти максимум limit_kind в таблицах - это и будет необходимо значение. Правда теперь стоит учитывать, что дата в limit_kind может изменится в течении сессии. В начале, когда не было ни одной сделки, там будет текущая дата, что соответствует Т+0, а после там может быть завтра, что уже будет Т+1. Что тоже явно противоречит спецификации инструмента, т.к. режим расчётов условно постоянен и не изменяется в течении сессии.
Как писал выше, проще всего создать bat файл, в него поместить все команды и выполнить его в Comand Promt в каталоге где находятся исходники. Собственно ошибка-то даже по-русски пишет, что нет файла в каталоге запуска.
Для сборки mySql будут совсем другие команды link, так что это уже совсем другой вопрос.
Библиотеки скачиваются с сайта LUA. Именно библиотеки. Можно, конечно, и самому собрать из исходников.
Это команды сборки в среде х64 command promt VS - терминал. Можно сделать bat файл с этим содержимым и запустить его в среде x64. Т.е. это не особенность Lua, а просто сборка dll из исходников.
Именно в таком виде, нужна dll, да. Но вопрос бы про интерфейс управления скриптом. Ответ - достаточно табличных форм qlua. Главная цель же - это скрипт и его работа, а форма управления, даже если она не имеет выпадающих списков, колесиков и прочей, позволяющая редактировать параметры, вполне достаточна.
Если нет ответа транзакции (т.е. ответа шлюза биржи), то, скорее всего, транзакция не прошла дальше сервера брокера. А значит есть ответ и ошибка самого метода sendTranscation. Где тоже необходимо проверять - ушла ли транзакция на биржу.
Не очень понятно почему должен быть вызван колбек OnOrder, если никаких изменений с ордером не произошло. Что касается колбека OnTransReply, то использовать его для проверки состояния сессии - это так себе идея. Сессия может быть приостановлена, закрыты торги по инструменту, просто не допущен к торгам в это время и т.д. При этом "долбить" сервер транзакцией в надежде "а вдруг" не даст результата. да и брокер может сказать на это "фи".
У каждого метода есть своё предназначение. Транзакция - для подачи торговых команд и только. Подавать их необходимо когда торги по инструменту проводятся. Поэтому необходимо проверять состояние сессии перед подачей торговой команды.
Правда пример функции не самый удачный, на мой взгляд. Но это дело вкуса, не более. Лишь бы работало.
т.е. необходимо иметь массив для EMA, либо при появлении нового бара запоминать прошлое значение и рассчитывать новое на базе одного и того же прошлого для всех вызовов в этом новом баре.
Ваша реализация постоянно обновляет прошлое. Важно учитывать, что вызов OnCalculate происходит для каждой (условно) сделки в новом баре, а не один раз при появлении нового бара.
Для данных по стакану есть параметры в таблице текущих торгов. Есть и сумма по заявкам, есть и по объёму в этих заявках.
BIDDEPTH - Спрос по лучшей цене BIDDEPTHT - Суммарный спрос NUMBIDS - Количество заявок на покупку OFFER - Лучшая цена предложения OFFERDEPTH - Предложение по лучшей цене OFFERDEPTHT - Суммарное предложение NUMOFFERS - Количество заявок на продажу HIGHBID - Лучшая цена спроса сегодня LOWOFFER - Лучшая цена предложения сегодня
nikolz написал: Хорошо, что признали. ------------------ Не увидел в вашем примере этого. ------------------ Что не так в этих данных. 1. mem 285.5576171875 2. mem 284.5439453125 3. mem 284.751953125 4. mem 284.6689453125 ----------------- Где Ваши доказательства? Можете, не перескакивая, конкретно показать , что и как Вы сокращаете?
Что я должен был признать? Впрочем, я уже ответил, что я не буду спорить. Мне хватает своих глаз для принятия решений. Вы можете продолжать спорить с другими.
nikolz написал: Вы ошибаетесь. Ваш пример не соответствует Вашему t3[i=3]=nil ---------------- В Вашем тесте есть оператор tt1=nil (стр 21) Именно этот оператор освободит память так как он обнуляет ссылку на таблицу , т е массив из кучи становится без ссылки. Его и удаляет сборщик. --- если закомментировать tt1=nil. то результат: ------------- 1. mem 285.5576171875 2. mem 284.5439453125 3. mem 284.751953125 4. mem 284.6689453125 ------------ никакой очистки нет, как я Вам и написал.
Я знаю, что без удаления ссылки самой таблицы, расстановка nil по элементам массива ничего не даст. Пример говорит о другом. Очистка всей таблицы собирает её всю, да. Но он добавлен для того, чтобы видеть какой объём занимает вся таблица, заполненная значениями double.
Второй пример показывает какой размер забирает скрипт при работе с таблицей с дырками. Именно такие и используются при расчёте по индексам ряда. Спорить желания нет, т.к. это эмпирически проверено, даже просто по наблюдаемому объёму занимаемой памяти в окне доступные скрипты.
VPM написал: paluke, Я тоже проверил, действительно второй элемент зачищен? Хотя структура таблицы должна сохраниться, как утверждает nikolz,?
Он говорит о другом. Действительно, если инициализировать чистый массив, заполняя элементы последовательно, не допуская дырок, то тогда даже если пройтись по массиву и установить nil для каждого элемента, то память не освободится. Если же заполнять дырявую таблицу (а после третьего элемента она уже будет с дыркой), то это уже не массив и тогда мусорщик работает иначе.
VPM написал: Если не сложно, покажите на примере кода выше, Вашу реализацию фильтра. Как должно выглядеть?
Код
function Cached.Roofing_Filter(FSettings, ds)
-- Параметры
local ds = ds or nil
local FSettings = FSettings or {}
local v_t = FSettings.v_t or 'C'
local P = FSettings.period or 48
local N = FSettings.N or 10
local x = FSettings.x or nil
-- Локальные таблицы для хранения данных между вызовами
local Price, HP, SSF, Lead = {}, {}, {}, {}
local alpha1, a1, b1, c2, c3, c1 = 0, 0, 0, 0, 0, 0
local I1 = 0 -- Индекс предыдущего бара
-- Функция для ограничения размера таблицы
local function limit_table_size(tbl, max_size)
while #tbl > max_size do
table.remove(tbl, 1)
end
end
return function(I)
-- Текущая цена
local p0 = x or Value(I, v_t, ds) or 0
-- Проверка смены бара
local newbar = I > I1
if newbar then
-- Обновление индекса бара
I1 = I
-- Инициализация на первом баре
if I == 1 then
Price[I], HP[I], SSF[I], Lead[I] = p0, 0, 0, 0
local fi = (0.707 * 2 * math.pi / P)
alpha1 = (math.cos(fi) + math.sin(fi) - 1) / math.cos(fi)
a1 = math.exp(-1.41421356 * math.pi / N)
b1 = 2 * a1 * math.cos(1.41421356 * math.pi / N)
c2, c3, c1 = b1, -a1 * a1, 1 - c2 - c3
else
-- Обновление цены
Price[I] = p0
-- Разница цен для выделения высокочастотных компонентов
local p1 = Price[I - 1] or p0
local p2 = Price[I - 2] or p1
local noise = p0 - 2 * p1 + p2
-- Расчет HP-фильтра
local hp1 = HP[I - 1] or 0
local hp2 = HP[I - 2] or hp1
local hp = (1 - alpha1 / 2) * (1 - alpha1 / 2) * noise + 2 * (1 - alpha1) * hp1 - (1 - alpha1) * (1 - alpha1) * hp2
HP[I] = hp
-- Расчет SuperSmoother
local ssf1 = SSF[I - 1] or 0
local ssf2 = SSF[I - 2] or ssf1
local ssf = c1 * (hp + hp1) * 0.5 + c2 * ssf1 + c3 * ssf2
SSF[I] = ssf
-- Расчет опережающего сигнала (Lead)
local lead1 = Lead[I - 1] or 0
local lead = 2 * ssf - 1 * ssf2
Lead[I] = lead
end
-- Ограничение размера таблиц
limit_table_size(Price, 3) -- Храним только последние 3 бара
limit_table_size(HP, 3)
limit_table_size(SSF, 3)
limit_table_size(Lead, 3)
end
-- Возвращаемые значения
return Lead[I] or 0, SSF[I] or 0
end, Lead, SSF
end
local fAlgo, Lead, SSF = Cached.Roofing_Filter(FSettings, ds)
nikolz написал: Такая операция не освобождает память Вы просто в записываете тип элемента равным 0. Но элемент остается в таблице.
Так, да не совсем так. Это зависит от того в какую область попадёт ключ - в в массив или в хеш-мап Т.к. такая операция эмпирически проверена, и collectgarbage('count') явно показывает разницу, то в данном случае расход памяти уменьшается.
Для теста вот код, можно запустить как в чистом lua (тогда раскомментировать вызов main), так и в терминале.
Код
local last = os.clock()
print = _G.message or print
local sleep = sleep or function(ms)
last = os.clock()*1000
while (os.clock()*1000 - last) < ms do
end
end
local tt1 = {}
local tt2 = {}
local test = function()
for n = 1,10000 do
tt1[n] = 100.12345
end
print('1. mem '..collectgarbage('count'))
tt1 = nil
collectgarbage()
sleep(10)
print('2. mem '..collectgarbage('count'))
for n = 1,10000 do
tt2[n] = 100.12345
tt2[n-3] = nil
end
print('3. mem '..collectgarbage('count'))
collectgarbage()
sleep(10)
print('4. mem '..collectgarbage('count'))
end
function main()
test()
sleep(1000)
end
-- main()
1. mem 279.5498046875 1. mem 23.5576171875 3. mem 23.787109375 4. mem 23.7060546875 5. mem 23.787109375
Впрочем, для массивов фиксированного размера просто применяются кольцевые буферы.
VPM написал: Вы имеете в виду такой подход Table = x if I > I - 3 then Table = nil end
Просто t[i-3] = nil
Проверять не обязательно. Если всего три элемента, то да, можно и удаление со сдвигом использовать. Хотя? т.к. в таблицах Вы храните не числа 1, 2, 3, а номера индекса ... 1001, 1002, 1003 и т.д., то после сдвига выйдет 1001 = nil, 1002, 1003, 1004. Что равносильно t[1004-3] = nil
Это реализация из под кальки примеров расчёта индикаторов от ARQA. Они не столь удачны.
Для начала, если используется замыкание, то зачем же каждый раз передавать FSettings, ds. Это условно постоянные переменные. Они не изменятся для созданного экземпляра. Значит их можно передавать только при инициализации, а значит и параметры определить один раз. Постоянно изменяемая величина - это индекс, вот только её и передавать в экземпляр расчёта.
Метод table.remove не самый быстрый - очень не быстрый. Хотя, наверно, в рамках Квик это не столь критично, тем более, что расчёт раз в бар. Я предпочитаю просто очищать данные в таблицах, сборщик мусора освободит память.
Также я предпочитая возвращать инициализированный метод расчёта и таблицы, хранящие данные (в данном случае это Lead и SSF). Их необходимо иницализировать один раз и тогда всегда будет под рукой ссылка на весь массив данных, а нее только возвращаемые последние.
Для примера: local fCalc, Lead, SSF = Cached.Roofing_Filter(FSettings, ds)
И тогда расчёт выглядит элементарно:
fCalc(index)
А использование данных:
Lead[index], Lead[index-2] и т.д. Ссылка же неизменная, а значит нет необходимости получать из метода расчёта что-то ещё, засоряя память.
Никак. Более того это зависит от выбранного шрифта и его размера. Плюс надо не забывать, что есть шапка окна, её необходимо не включать в расчёты, т.к. она есть если строк 0. Так что я просто делаю доступным параметры масштабирования, чтобы можно было задать для каждого скрипта.
Да примерно всё также, три вклада, накопительный и четыре брокера. Я не буду заниматься переброской денег из банка в банк ради повышенных приветственных ставок. Я плачу налоги как с вкладов, так и с облигаций. Ранее, до 2021, ОФЗ были без налога, теперь есть. Также как и вклады от суммы 1 млн. Так что приходится платить и эти налоги. Что касается рисков, то я бы здесь поспорил, т.к. риски по банкам, где высокие проценты, выше. Например, я не могу открыть вклад с своих банках выше 22-23%. И это без капитализации и пополнения, т.е реальная ставка ниже. Поэтому те же ОФЗ, хоть и имеют процент ниже, но позволяют торговать волатильность без потери купонов. А флотеры по сути и есть аналог вклада, например 29014, 29106. Дают доходность как вклад, купоны раз в квартал, но тоже позволяют торговать их. Ставка зависит от RUONIA.
Что касается Самолёта, то это реальность - лесенкой собирал, лесенкой сдавал. Также как и по другим облигациям, которые упали после октябрьского заседания, а в декабре выстрелили обратно.
Что касается срочки, то я предпочитаю календарные спреды. Простые фьючи тоже торгуются, но чаще это просто позиция для защиты. Заниматься спекуляциями как работой желания нет, банально надоело.
VPM написал: Я же рассуждаю об инвестиционной стратегии. То есть вопрос стоит фиксировать или нет, если фиксировать кто лучшей из ОФЗ? В декабре 24 я немного взял 33 с доходностью на тот момент > 20%. Короткие корпоративные супер, но это спекулятивная стратегия в моем понимании. Для инвестирования я еще смотрю на выпуски номинированные в USD?
Для облигаций есть достаточно инвестиционных стратегий, например Колесо. В моём понимании надо иметь три части в облигациях: 1. фиксированный купон - это фиксация, но набирать надо когда есть дисконт к цене. 2. флоатеры - это как раз аналог вклада. Получаете текущий средний процент на рынке, не думая ни о чём. Например 29014, 29016 и далее. 3. торговля тела - т.е. покупаем на просадках, продаём на росте. При этом эта часть может дать даже намного больше, чем купоны.
Что выбирать - дело субъективное. Кто-то боялся покупать облигации Самолёт недавно, а кто-то за несколько дней собрал десятки процентов от тела. Достаточно было читать отчёт компании, а не потоки анал-итики. Да, риски есть всегда. Но если их исключать (почти), то взять ОФЗ ПК и ПД раных дюраций и не думать. Тем более, что есть RGBI фьючерс. С ним можно еще и расхождения торговать, да и просто как хедж брать.
Что касается 248, то я бы её рассматривал если есть ожидания снижения ставки. Собственно как любая длинная. Да, у неё большой купон YTM - это хорошо. Но я уже с 98 года не планирую далее 3-х лет. А сейчас и более полугода. Так что предпочитаю собирать доход сейчас, а не потом.
Сейчас ОФЗ тоже под налогом. Если только не ИИС на длительный строк. Основная идея облигаций не в этом, а в том, что они позволяют получать доход как от купона, так и от переоценки тела. И без потери начисленных купонов. Также стоит учитывать, что эти 24% вклада - это итоговая ставка дохода, сложный процент будет ниже. А вот в облигациях как раз можно реальную доходность получить выше, т.к. выплата купонов может быть раз в квартал или даже в месяц. А если говорить о том, что облигации тоже ходят каждый день на 0.5% и более, то и это можно торговать сеткой. Иногда в день до 5-10 сделок бывает.
nikolz написал: Идея понятна. Но Вы не пробовали посчитать в сравнении с депозитом в банке и учетом сложного процента. Недавно читал статью в инете где говорится что высокие проценты по облигациям на длительный срок реально дают более низкий процент чем депозит если разложить эти процента по годам с учетом сложного процента.
Скорее наоборот. Эти 24 в банке - это, скорее всего, без капитализации и на длительный срок. С облигациями это не так. Например, облигации с купоном каждый месяц уже дают намного больший денежный поток. Плюс еще переоценка тела. Также облигации, как и любой торгуемый инструмент позволяет собирать волатильность, т.е. торговать небольшие движения. Это как выйти из вклада через неделю без потери процентов. Так что нет, вклады хоть и спокойней, но облигации могут дать намного больше. Правда для этого надо приложить немного усилий.
Что касается ожиданий, то да 38-мые могут выстрелить. Впрочем, ОФЗ - как вклады в банках. Можно зафиксировать доходность на года и выйти в любой момент. А для спекуляций, например, совсем недавно облигации Самолет давали под 50%. Или Россети ЛЭ, да и тот же недавно размещённый Магнит. Я люблю короткие облигации с 30-и дневной выплатой.
Kolossi написал: Большое спасибо Катерина за развернутый ответ. Я порекомендую брокеру уточнить у биржи будет ли ему представлен доступ к к торговле в выходные дни. А сам буду каждое субботнее утро в 7-00, 10-00 и в 19-00 проверять статус каждого тикера составлять список инструментов допущенных к торговле на отдельной бумажке и потом из нее создам для робота таблицу рекомендуемых тикеров на воскресенье. Но может все-таки это будет параметр для getParamEx?
Они рекомендую как раз два параметра STATUS и TRADINGSTATUS. Первый не все брокеры транслируют. Второй, вроде, все.
Если для параметра TRADINGSTATUS вернулся result == '1', то можно увидеть идут ли торги по значению param_value из возвращаемой таблицы. Здесь на форуме были как-то написаны значения.
Правда для срочного рынка надо еще смотреть на параметр CLSTATE.
Речь о поведении данных в таблице money_limits поле limit_kind. Вы предложили реализацию через перебор данных и поиск максимального. Такой подход возможен, да. Но возникает вопрос - почему вносимые изменения потребовали использования такого подхода.
limit_kind - это режим торгов инструмента, он задан в его спецификации и не изменится в течении торговой сессии. Наоборот, это достаточно постоянный параметр. То что дата расчётов в связи с выходными может быть дальше, не означает, что необходимо теперь переходить на хранение даты. То что в течении торговой сессии произошли с сделки с инструментом, не означает, что его режим торгов изменится. Он как был Т+1, так и остался. Просто позиция будет той же завтра, если нет сделок, не более. Сейчас же происходит замечательная вещь - нет сделок, получаем режим торгов Т+0 (текущая дата), совершили сделки, получаем Т+1 (следующая дата). Т.е. можно было бы добавить дату расчётов в таблицу, чтобы знать когда произойдут взаиморасчёты, но базовый фильтр limit_kind почему был изменён - совершенно не ясно. Это не дата расчётов. С этим можно было жить как раньше, если бы он не изменялся в течении торгов, но и это не так. Теперь действительно необходимо постоянно сканировать на поиск максимального значения.
Хотя нет, это ваша реализация так работает. Прямой фильтр по money_limits требует точного соответствия. Это, конечно, просто великолепно вносить изменения ломающие обратную совместимость в ключевые механизмы по работе с инструментами.
В данной схеме обнаружена она проблема, затрудняющая её использование. В таблице money_limit поле limit_kind может изменится в процессе работы. Например, считываем данные по инструменту, по которому нет позиции, получаем текущую дату. Открываем позицию и в поле limit_kind уже дата +1. Не очень понятно как предлагается работать, если данные параметр будут постоянно изменяться. Если только просто не прибавлять всегда 1, т.к. заявляется, что вернётся ближайшее значение.