Здравствуйте форумчане и разработчики. Прошу пояснить такой вопрос - как работает функция OnCalculate(). Я кодом Lua выбрасываю на график две метки, затем перемещаю их руками и затем провожу расчет индикатора на интервале между метками. Ожидал, что все линии индикатора изменятся после расчета. Но...алгоритм работы функции OnCalculate() не соответствует моим ожиданиям. На скрине ниже все видно - сначала выводятся рассчитанные значения до перемещения меток и только на последней свечке (по приходу тиков) выводятся рассчитанные значения. Это так задумано изначально?
Добрый день. Все верно, функция OnCalculate() срабатывает при появлении нового значения на графике. Если вы хотите безусловное срабатывание OnCalculate(), то можно воспользоваться функцией: SetValue: Функция предназначена для установки указанного значения на выбранной линии определенной свечи индикатора.
Спасибо Егор. Еще один вопрос - будет ли корректно отрабатывать SetValue() если ее вызовы будут находится в другой функции ( в ней в цикле рассчитываются сразу все значения, которые необходимо вывести ), вызываемой из OnCalculate(), или ее необходимо разместить в теле OnCalculate(). Пример:
Код
function GETTRENDLINE(APntIdx,APntLvl,BPntIdx,BPntLvl,koe)
local Line
local indx
local TrLine
--g_PriceStep
--g_PriceScale
indx=Size();
--message(tostring(indx));
for i=0,indx do
if indx < APntIdx then
SetValue(i, 1, nil)
else
if indx > BPntIdx then
SetValue(i, 1, nil)
else
if indx==APntIdx then
SetValue(i, 1, APntLvl)
end
if indx==BPntIdx then
SetValue(i, 1, BPntLvl)
end
if indx>APntIdx then
if indx<BPntIdx then
TrLine=math_round(APntLvl*koe,g_PriceScale)
SetValue(i, 1, TrLine)
end
end
end
end
end
return
end
Здравствуйте. Простейший индикатор на минутном графике работает когда его добавляешь на график. После перезагрузки без конца квик то подключится, то отключится, постоянно выводит информационное окно с разными сообщениями, получается всё время циклится - висит. Индикаторов таких несколько на разных графиках. Чтобы после перезагрузки вообще загрузиться приходится переименовать папку LuaIndicators, тогда удаётся зайти в квик и работать. Чтобы запустить графики, надо опять переименовать папку обратно в LuaIndicators, удалить на каждом графике индикатор и загрузить индикатор заного. Для тестирования ошибки оствил один график и один свой индикатор, так же попробовал в режиме ЗАМЫКАНИЙ. Кстати совсем не понятно, что это за режим такой и зачем он нужен, чем он отличается от обычного режима - очень хотелось бы получить на это ответ. Ну так вобщем сделал из индикатора совсем наипростейший, фактически оставив там только return nil и всё, тестил далее в режиме ЗАМЫКАНИЙ, так как никаой разницы с простым режимом не увидел. В теле OnCalculate поставил вывод через PrintDbgStr("Index = " .. tostring(index)). И что получилось. Судя по выводам отладки видно, что все свечи вызываются последовательно начиная с 1 и до какой-то свечи, потом опять с 1 и до какой-то свечи, потом опять, короче раза 3 или даже 4 прогоняются свечи с 1 до последней. На этом всё. Болеее функция OnCalculate вообще НЕ ВЫЗЫВАЕТСЯ!!! График при этом работает, свечи на нём идут, а OnCalculate не вызывается ВООБЩЕ. Почему такое? Почему при добавлении графика работает и OnCalculate вызывается и не один раз даже на свечу минутную, а при перезагрузке вызываются какие-то старые не нужные мне свечи последовательно и причём не один раз, а при приходе новых свечей OnCalculate перестаёт вызываться. И что за ЗАМЫКАНИЯ такие, как их использовать и в чём их смысл?
А, ещё добавлю. В тестовом режиме по крайней мере хоть виснуть перестал, хотя всё равно при входе то подключится квик, то отключится и так несколько раз, хотя потом вроде подключается окончательно и более не отключается. Но это так и раньше было до индикаторов. Может из-за того, что на каждом индикаторе много рассчётов было и поэтому из-за этого квик постоянно подключался-отключался и не мог совсем из этого режима выйти - фактически как висел, а когда упростил индикатор до немогу и оставил его один на одном графике, тогда квик таки соизволил выйти из этого бесконечного цикла подключился-отключился от сервера.
Вобщем сейчас долго тестит-тестил. Оказалось, что простейший индикатор всё-таки свечки новые вызывают вызов функции OnCalculate. Просто новых выводов функции PrintDbgStr в окне DebugView не было видно, что они появляются снизу как и положено видимо потому, что очень много инфоормации в окне накопилось и чтобы их увидеть, что они действительно пиишли надо было понажимать PageDown клавишу и тогда их видно новые, а я мышкой пытался двигать позунок вниз и ничего не происходило, чтобы мышкой двинуть оказывается надо сначала вверх ползунок двинуть, а потом вниз до конца - только тогда окно отображет последние выводы, а если только ползунок вниз до конца, то так не катит, такие особенности вот, ктоб знал, что у них так, раньше всегда просто вниз ползунок и всё видно что последнее в окно пришло.
Не нужные мне свечки ранее отсекал сохранение значения через вызов функции Size(), обрабатывал только вновь пришедшие свечи. При загрузке индикатора такое работало. После перзагрузки Size() внутри Init возвращает 0, буду пробовать выкручиваться, может отсекать свечи до подключения и после подключения? Попробую, а то виснет же - видимо много считает и считает при загрузке.
Alexander написал: Не нужные мне свечки ранее отсекал сохранение значения через вызов функции Size(), обрабатывал только вновь пришедшие свечи. При загрузке индикатора такое работало. После перзагрузки Size() внутри Init возвращает 0, буду пробовать выкручиваться, может отсекать свечи до подключения и после подключения? Попробую, а то виснет же - видимо много считает и считает при загрузке.
Бесплатные советы. 1) Если вы про замыкание в луа, то рекомендую читать это: https://eligovision.ru/media/upload/lua.pdf 2) Чтобы индикатор рассчитывался лишь по закрытым свечам используйте условие появления новой свечи. т е поставьте if по смене параметра OnCalculate(i) Например так
Код
local _i=0
function OnCalculate(i)
if i~=_i then
---что-то делаете
_i=i
end
return ... -вывод индикаторов
end
1) Посмотрю. Вникну подробнее. Мельком глянул - ничего с наскоку не понял. Для чего эти замыкания в квике в индикаторах? Если можно на пальцах, хоть кратко, просто для того, чтобы уловить суть необходимости. 2) Не, мне так не пойдёт. Это отсекёт повторы если будут, а так то всё-равно все свечи пробегать будет. А мне надо, чтобы "старые"(до момента коннекта) все отбрасывались. Я в принципе уже нашёл решение как это сделать, хотя и Size() в Init возвращает 0 при запуске квика с индикаторами. Вызыываю Size() только после коннекта с сервером и только 1 раз, чтобы зафиксировать значение и обрабатываю свечи > этого значения только. Несколько вызовов на 1 свечу мне не страшно, пусть будут, график рисует как надо. А так то да, можно использовать, чтобы одну свечу 1 раз только вызывать, может и заиспользую.
1) Посмотрю. Вникну подробнее. Мельком глянул - ничего с наскоку не понял. Для чего эти замыкания в квике в индикаторах? Если можно на пальцах, хоть кратко, просто для того, чтобы уловить суть необходимости. 2) Не, мне так не пойдёт. Это отсекёт повторы если будут, а так то всё-равно все свечи пробегать будет. А мне надо, чтобы "старые"(до момента коннекта) все отбрасывались. Я в принципе уже нашёл решение как это сделать, хотя и Size() в Init возвращает 0 при запуске квика с индикаторами. Вызыываю Size() только после коннекта с сервером и только 1 раз, чтобы зафиксировать значение и обрабатываю свечи > этого значения только. Несколько вызовов на 1 свечу мне не страшно, пусть будут, график рисует как надо. А так то да, можно использовать, чтобы одну свечу 1 раз только вызывать, может и заиспользую.
1) про замыкания. индикаторы здесь не причем. Это способ программирования функций, при котором значения переменных сохраняются после выхода из функции. Он используется в различных языках программирования. Не знает, не используйте. тоже самое делают глобальные переменные. -------------- 2)если надо не обрабатывать старые, то сравнивать i с size()
nikolz написал: 1) про замыкания.индикаторы здесь не причем. Это способ программирования функций, при котором значения переменных сохраняются после выхода из функции.Он используется в различных языках программирования.Не знает, не используйте. тоже самое делают глобальные переменные.--------------2)если надо не обрабатывать старые, то сравнивать i с size()
1) Про замыкания возник вопрос из-за того, что у кваика есть справочный .pdf файл "Использование Lua в Рабочем месте QUIK.pdf" в C:\Open_Broker_QUIK\Doc\Lua, в нём есть п. 3.7 "Расчёт EMA" и там написано: "Нет возможности обратиться напрямую к предыдущим рассчитанным значениям индикатора. Это значит, что для вычислений текущего значения необходимо хранить и предыдущие значения. Для таких целей в Lua используется механизм замыканий. Определение такой функции нужно вынести в отдельный файл и в отдельный каталог, который не сканируется при создании индикатора." И далее идут примеры, функции, возвращающие функции(короче замыкания как я понял). Они используются именно для индикаторов. В чём там прикол, я так и не понял. Можно тоже самое написать и не использовать возврат функции в функции(замыкания). Что они хотели этим показать я не понял. И зачем это всё в отдельный каталог, который не сканирует квик при создании индикатора? Зачем весь этот изврат с каталогами, dofile и замыканиями в придачу??? 2) Это да согласен, что i c Size() надо тогда сравнивать, это так. Просто у меня сначала скрипт начинался с того, что в init сначала запоминал Size(), а в OnCalculate() отбрасывал всё, что меньше Size(), повторные свечи >= Size() тоже обрабытывал, для меня это не важно было. Вобщем такой скрипт при загрузке на индикатор нормально загружался и работал без проблем, рисовал кривые мои 2 шт в отдельной области. Проблема возникла только тогда, когда я выходил из квика, повторно запускал квик и вот тут то квик у меня вообще начал зависать, вернее в цикле без конца то подключится к серверу, то отключится, при этом куча окон всяких на экран выдаёт, в сам квик войти невозможно стало. А чтобы зайти нужно было как то отключить индикаторы. Я даже по началу вообще не понял, что в этом виноваты мои индикаторы, так как проблема то явно выглядела как подключения-отключения к серверу. Потом дошло, что могут влиять на это индикаторы. А как их отключить то если квик не запускается. Вот пришлось переименовывать папку с индикаторами, чтобы квик при загрузке их не находил. Папку переименовал, в квик стал заходить, ну иначал искать причину чё к чему. Выяснил, что квик этот почему-то еще до коннекта с сервером по паролю 2 раза(зачем 2 не знаю, только разрабам видно известно) пробегает по свечам по всем начиная с первой, потом после второго прогона останавливается и пока не залогинишься более никакие свечи не прогоняет. Потом как залогинишься квик опять таки ещё 2 раза опять заного пробегает по всем свечам(точно так же как и до залогинивания) но потом уже начинает и дальше свечи обрабатывать, что новые грузит. Так вот в самый первый раз до залогинивания Size() выдаёт почему-то 0(ноль) Ха - ха - ха Ноль, а не то что надо - максимальный индекс свечи. Отсюда получалось то, что даже при закрузке квика(после переименования папки с индикаторами) и при работающем квике если название папки с индикаторами вернуть обратно, то индикаторы то всё равно не заработают на открытых графиках, а чтобы заработали надо зайти в график, удалить их и заного загрузить на график, только тогда квик их загрузит из папки. Ну а потом я эту проблему решил как описал выше через isConnected() и подкорректировал всю логику индикатора, убрав Size() из Init. Просто вычислений на свечу видимо много было и квик так долго всё обсчитывал и обсчитывал, что не догонял чё так долго то и разрывал соединение установленое с сервером, потом опять по кругу - подключался, считал, отключался и т.д. и т.п. Потом, когда сделал так, что Size() начал мне выдавать нормальное значение вместо ноля, квик стал подключаться, так как все свечи до логина мой индикатор считал в nil, а потом отсчитыал только свечи новые, видимо так как новые то идут не так часто, квику хватает времени и на свою работу и на просчёт свечей. Всё стало работать. А так то это их косяк - почему Size() выдаёт ноль если он в Init и квик загружается с существующим ранее индикатором? Ведь всечи то есть и он их прогоняет до какого-то значения аж 2 раза. Почему же тогда Size() не возвращает это значение? Вот в этом и косяк. Не будь его всё бы работало и в процессе загрузки на индикатор и после перзагрузки, ан нет, пришлось извращаться и корректировать код.
А на счёт замыканий я раньше и не слыхал. Может в интерпретируемых языках такое есть? Типа Lua, Pyton и прочих? На си так вообще никаких проблем с такими переменными нет. Передал в функцию переменные не явно, а по ссылке, или просто их адреса(что с точки зрения компиляции одно и тоже фактически будет) и все дела. Явные то переменные через стек в функцию попадают, после выхода из функции стек режется и переменные пропадают, а по ссылке или через адрес функция обращается к ним не через стек, а через косвенную адресацию. Поэтому эти переменные при выходе из функции сохранятся после их изменения внутри функции. Может из-за того, что интерпретируемые языки так не могут ввиду их простоты, поэтому и ввсели эти замыкания. Но это только догадки. Пока я сам в смысл этих замыканий ещё не вникал, не читал ещё.
nikolz написал: 1) про замыкания.индикаторы здесь не причем. Это способ программирования функций, при котором значения переменных сохраняются после выхода из функции.Он используется в различных языках программирования.Не знает, не используйте. тоже самое делают глобальные переменные.--------------2)если надо не обрабатывать старые, то сравнивать i с size()
1) Про замыкания возник вопрос из-за того, что у кваика есть справочный .pdf файл "Использование Lua в Рабочем месте QUIK.pdf" в C:\Open_Broker_QUIK\Doc\Lua, в нём есть п. 3.7 "Расчёт EMA" и там написано: "Нет возможности обратиться напрямую к предыдущим рассчитанным значениям индикатора. Это значит, что для вычислений текущего значения необходимо хранить и предыдущие значения. Для таких целей в Lua используется механизм замыканий. Определение такой функции нужно вынести в отдельный файл и в отдельный каталог, который не сканируется при создании индикатора." И далее идут примеры, функции, возвращающие функции(короче замыкания как я понял). Они используются именно для индикаторов. В чём там прикол, я так и не понял. Можно тоже самое написать и не использовать возврат функции в функции(замыкания). Что они хотели этим показать я не понял. И зачем это всё в отдельный каталог, который не сканирует квик при создании индикатора? Зачем весь этот изврат с каталогами, dofile и замыканиями в придачу??? 2) Это да согласен, что i c Size() надо тогда сравнивать, это так. Просто у меня сначала скрипт начинался с того, что в init сначала запоминал Size(), а в OnCalculate() отбрасывал всё, что меньше Size(), повторные свечи >= Size() тоже обрабытывал, для меня это не важно было. Вобщем такой скрипт при загрузке на индикатор нормально загружался и работал без проблем, рисовал кривые мои 2 шт в отдельной области. Проблема возникла только тогда, когда я выходил из квика, повторно запускал квик и вот тут то квик у меня вообще начал зависать, вернее в цикле без конца то подключится к серверу, то отключится, при этом куча окон всяких на экран выдаёт, в сам квик войти невозможно стало. А чтобы зайти нужно было как то отключить индикаторы. Я даже по началу вообще не понял, что в этом виноваты мои индикаторы, так как проблема то явно выглядела как подключения-отключения к серверу. Потом дошло, что могут влиять на это индикаторы. А как их отключить то если квик не запускается. Вот пришлось переименовывать папку с индикаторами, чтобы квик при загрузке их не находил. Папку переименовал, в квик стал заходить, ну иначал искать причину чё к чему. Выяснил, что квик этот почему-то еще до коннекта с сервером по паролю 2 раза(зачем 2 не знаю, только разрабам видно известно) пробегает по свечам по всем начиная с первой, потом после второго прогона останавливается и пока не залогинишься более никакие свечи не прогоняет. Потом как залогинишься квик опять таки ещё 2 раза опять заного пробегает по всем свечам(точно так же как и до залогинивания) но потом уже начинает и дальше свечи обрабатывать, что новые грузит. Так вот в самый первый раз до залогинивания Size() выдаёт почему-то 0(ноль) Ха - ха - ха Ноль, а не то что надо - максимальный индекс свечи. Отсюда получалось то, что даже при закрузке квика(после переименования папки с индикаторами) и при работающем квике если название папки с индикаторами вернуть обратно, то индикаторы то всё равно не заработают на открытых графиках, а чтобы заработали надо зайти в график, удалить их и заного загрузить на график, только тогда квик их загрузит из папки. Ну а потом я эту проблему решил как описал выше через isConnected() и подкорректировал всю логику индикатора, убрав Size() из Init. Просто вычислений на свечу видимо много было и квик так долго всё обсчитывал и обсчитывал, что не догонял чё так долго то и разрывал соединение установленое с сервером, потом опять по кругу - подключался, считал, отключался и т.д. и т.п. Потом, когда сделал так, что Size() начал мне выдавать нормальное значение вместо ноля, квик стал подключаться, так как все свечи до логина мой индикатор считал в nil, а потом отсчитыал только свечи новые, видимо так как новые то идут не так часто, квику хватает времени и на свою работу и на просчёт свечей. Всё стало работать. А так то это их косяк - почему Size() выдаёт ноль если он в Init и квик загружается с существующим ранее индикатором? Ведь всечи то есть и он их прогоняет до какого-то значения аж 2 раза. Почему же тогда Size() не возвращает это значение? Вот в этом и косяк. Не будь его всё бы работало и в процессе загрузки на индикатор и после перзагрузки, ан нет, пришлось извращаться и корректировать код.
проблему с отключением индикатора я решаю так : Перед запуском квика в индикаторе пишем аброкадабру т е делаете явно ошибки. При запуске КВИК грузит индикаторы, а при их загрузке работает компилятор байткода. Он находит ошибку и квик такой индикатор не загружает. --------------------- Про два раза, да я тоже когда-то возмущался этим. Первый раз Size меняется до максимального. А второй раз он уже не меняется пока не придет новая свеча. Я делал так, чтобы считалось лишь один раз, но есть хитрость двух разового расчета . Поэтому просто забил на это. --------------------- Бесплатный совет. Так как Вы начинающий писатель, то рекомендую Вам писать скрипты без циклов. Так пишут профи софт для систем обработки данных в реальном времени. Если научитесь, то индикаторы будут в десятки раз считаться быстрее. ----------------------
nikolz написал: проблему с отключением индикатора я решаю так :Перед запуском квика в индикаторе пишем аброкадабру т е делаете явно ошибки. При запуске КВИК грузит индикаторы, а при их загрузке работает компилятор байткода. Он находит ошибку и квик такой индикатор не загружает.
Как вариант можно да, если один индикатор. У меня несколько, поэтому проще думаю переименовать LuaIndicators. В любом случае индикаторы не загрузятся. Но лучше конечно, чтобы они загружались и исправно работали.
Вернее индикатор(код) один, а на инструменты разные код в начале прописан, вот и получается, что если хочу установить на новый инструмент, то в начале меняю код инструментов ClassCode, SecCode, а остальной код оставляю как есть. Поэтому плодиться скрипты могут по мере того, что мне надо. Хотя вот думаю надо универсальный сделать через getDataSourceInfo().
nikolz написал: Про два раза, да я тоже когда-то возмущался этим. Первый раз Size меняется до максимального. А второй раз он уже не меняется пока не придет новая свеча. Я делал так, чтобы считалось лишь один раз, но есть хитрость двух разового расчета . Поэтому просто забил на это.
Этот Size() я ранее вызывал в Init. При загрузке индикатора он показывает последний индекс последней свечи. При загрузке квика ещё до логина с сервером если Size() остаётся в Init, то он возвращает НОЛЬ! А при ноле логика скрипта не работает. OnCalculate делает проверку индекса свечи с сохранённым Size(), чтобы отбросить всё что меньше, а там ноль. Поэтому, чтобы не менять логику с Init убрал Size() и начинаю его вызывать только после isConnected() == 1 и только 1 раз внутри OnCalculate(1 раз чтобы - использую флаг true/false). Так логика остаётся прежней и Size() возвращает уже не ноль. Хотя как вариант с первого пробега по свечам можно брать последнее максимальное значение(при этом возвращая везде nil), а при втором прогоне откидывать все свечи до максимальной с первого прогона так же возвращая везде nil, а потом уже начинать обрабатывать новые свечи, но так логика кода будет совсем иной(по Вашему примеру как-то так). Да, и ещё про 2 прогона, что Вы пишете - это когда индикатор грузится на график, а если загружается квик, то сначала идёт 2 прогона до одного максимального значения каждый, а потом после коннекта с сервером(ввод логин/пароля) происходит ещё 2 прогона и только последний, т.е. фактически 4-й по счёту начинает считать новые свечи с сервера.
nikolz написал: Бесплатный совет.Так как Вы начинающий писатель, то рекомендую Вам писать скрипты без циклов.Так пишут профи софт для систем обработки данных в реальном времени.Если научитесь, то индикаторы будут в десятки раз считаться быстрее.
Да в этом индикаторе нет никаких циклов вообще, он наипростейший до немогу. Мне по сути то вообще и свечи эти не нужны и считать мне по ним ничего не надо. Мне надо было в реальном времени отображать 2 объёма в стакане - для BID и OFFER для инструмента. И чтобы эти объёмы в виде кривых соотносились с графиком инструмента. Т.е. я OnCalculate() просто использую как функцию для расчёта в реальном времени этих нужных мне объёмов. Свечи как таковые с их данными просто игнорирую. Резульаты расчёта 2-х объёмов вывожу через return. Расчёт каждого объёма по любому в цикле, так как надо же пробежаться по стакану.
Вообще эти свечи все "старые", как и вообще весь этот ТА как по мне, так это всё ерунда. Что бы там не рисовал нам ТА, рано или поздно он соврёт. Анализировать конечно можно, но нужен чисто свой ТА, котрый будет работать по набору чисто твоих данных, которые могут динамически менятся во времени от разных ситуаций, да и сам алгоритм ТА нужно постоянно менять под меняющийся рынок. Только так ТА будет работать. Но это такие сложности постоянно обновлять входящие данные и их количество и постоянно корректировать код(и то только после определённого слежения за рынком), а как поменяется код, то нет никаких гарантий, что рынок не изменится и код будет рабочим определённое время. Вобщем ТА не вариант в плане свечей и графиков прошлых цен, вернее вариант, но очень сложный, требующий постоянной корректировки скрипта. А вот анализ стакана может помочь при дневных сделках и общем анализе ситуации на рынке если мониторить несколько инструментов например основных фишек индекса.
Alexander написал: Вообще эти свечи все "старые", как и вообще весь этот ТА как по мне, так это всё ерунда. Что бы там не рисовал нам ТА, рано или поздно он соврёт. Анализировать конечно можно, но нужен чисто свой ТА, котрый будет работать по набору чисто твоих данных, которые могут динамически менятся во времени от разных ситуаций, да и сам алгоритм ТА нужно постоянно менять под меняющийся рынок. Только так ТА будет работать. Но это такие сложности постоянно обновлять входящие данные и их количество и постоянно корректировать код(и то только после определённого слежения за рынком), а как поменяется код, то нет никаких гарантий, что рынок не изменится и код будет рабочим определённое время. Вобщем ТА не вариант в плане свечей и графиков прошлых цен, вернее вариант, но очень сложный, требующий постоянной корректировки скрипта. А вот анализ стакана может помочь при дневных сделках и общем анализе ситуации на рынке если мониторить несколько инструментов например основных фишек индекса.
Для такого ТА использую нейронные сети. -------------------- Относительно пользы свечей и "старых" свечей Вы заблуждаетесь. ================= Мое мнение следующее: ------------------- Любая история полезна для прогноза будущего поведения ее участников. ------------------- Любая тварь действует на основе накопленного опыта, т е прошлых ошибок и достижений. -------------------- Поэтому без прошлого нельзя прогнозировать будущее. ---------------------- Чем больше интервал наблюдаемого прошлого , тем дальше горизонт прогнозируемого будущего. Если торгуете на основе стакана, то горизонт такого прогноза измеряется в миллисекундах. Так торгуют HFT роботы. Но это очень дорогая технология и ее применяют лишь крупные игроки.
nikolz, А моё мнение следующее: Никакая история нафиг не нужна для прогноза будущего поведения. На нейронные сети могут надеяться лишь те, у кого напрочь ампутированы собственные мозги. Наблюдаемое прошлое не имеет никакого отношения к будущему поведению. Суходрочка в стакане и вообще HFT является лучшим доказательством отсутствия нормального алгоритма торговли.
Спорить ни с кем не буду. У каждого своё мнение. nikolz: "Поэтому без прошлого нельзя прогнозировать будущее" - здесь скажу, что прогнозировать без прошлого конечно нельзя, ибо вообще тогда и прогнозировать-то по сути нечего будет, но один хрен точно спрогнозировать это прошлое всё равно не поможет, будущее будет не таким как прогнозы в 99% случаев, а то и больше. Владимир: "Суходрочка в стакане и вообще HFT является лучшим доказательством отсутствия нормального алгоритма торговли." - тут по поводу HFT не знаю вообще ничего, а индикаторы рисуют графики по стаканам в качестве тестирования, мониторинга ситуации в течении дня, анализируются мной(не роботом, не индикатором) пары - и базовый актив и фьючер одновременно на разных графиках, тенденции они показывают чётко, например приближение к поддержке или сопротивлению существующим или новым(графики с линиями этого не покажут или покажут ложные[исходя из "старых" данных]), практически с ооооочень высокой вероятностью! Решения на покупки-продажи принимаются не роботом в этом случае, не индикатором, а вручную после анализа. Пока ни разу не подводил такой подход. Всё в пределах дня в основном.
Это взял просто то, что прям сейчас есть. После максимумов на зелёном графике идёт рост цены, но анализировать надо пару графиков иначе не точно и брать более максимальные значения по амплитуде и более продолжительные, чтобы на обоих графиках была одна и та же тенденция, что на покупку, что на продажу. И как правило движение цены начинается после пересечений графиков.
Так что анализировать стакан вполне себе можно, и мне кажется даже нужно - работает лучше всяких там индикаторов по "старым" данным на графике и всякого ТА. Робот так же написал, тестирую, он и по стакану и по алгоритму работает в совокупности, чтобы меньше ошибок было.
Чтобы оттестировать робот, надо пробовать менять входные параметры его и постараться добиться "оптимальных", а для этого написаны другие скрипты-тестеры и по стакану и по динамике изменения цены в реалии, "старые" данные вообще не использую. На тестах отрабатывает вроде не плохо, но в любом случае корректировки делаю в нём данных постоянно после анализа за тестами и за рынком в целом. На рынке всегда есть какие-то закономерности, вот их и надо пробовать ловить, они меняются, но они есть и задача их выявлять и корректировать входные параметры для робота, а всякий анализ "прошлого" как по мне - так это наобум. Любой робот написанный один раз без корректировки алгоритма и входных данных рано или поздно, но начнёт ошибаться. Да и алгоритмы желательно иметь разные и соответственно разные скрипты запускать в зависимости от той или иной ситуации, одному роботу охватить "всё" не практично.
Рынок он динамичный и робот должен быть динамичным. Это самая сложная задача. Не знаю какие там нейронные сети что могут, но думаю, что сети эти пишет человек и по своему уму и всякое там обучение тоже основано на алгоритмах, которые пишет человек, универсального алгоритма обучения нет. Поэтому заморачиваться и писать самообучающийся робот - это какая-то неимоверная задача, и робот будет без конца расти в размере всё больше и больше и постоянно писать его как самообучающийся неимоверно сложно, запаришься такое писать. А доверять сторонним алгоритмам это так себе идея. Вот поэтому за обучение нужно отвечать самому, анализирую рынок, тесты скриптов, стаканы и прочее и всё это закладывать в разные алгоритмы, которые снабжать разными данными. Всё гениальное просто на самом деле, не надо шибко всё усложнять.
Alexander, Индикаторы, может, и рисуют графики по стаканам - никогда не пользовался ни тем, ни другим, ни третьим. Как, кстати, и поддержкой с сопротивлением. А все решения на покупки-продажи принимаются только роботом. Когда-то я пытался с ним соревноваться, но позорно проиграл. Да, и скрипт один-единственный на все случаи жизни.
Это взял просто то, что прям сейчас есть. После максимумов на зелёном графике идёт рост цены, но анализировать надо пару графиков иначе не точно и брать более максимальные значения по амплитуде и более продолжительные, чтобы на обоих графиках была одна и та же тенденция, что на покупку, что на продажу. И как правило движение цены начинается после пересечений графиков.
это Вы велосипед изобрели, называется индикатор "аллигатор" ------------------------- Относительно стакана. -------------------------- Стакан - это и есть прогноз будущего, та как в нем заявки - т е заявки на сделки в будущем с горизонтом в мс, так как через мс-сек стакан уже другой. -------------------- Именно по стакану и работают HFT роботы. Но горизонт их прогноза -здесь и сейчас. ---------------- Примерно 70% сделк на крупных биржах - это HFT роботы ------------------- Маркет-мейкер - это тоже HFT. -----------------
Владимир написал: Alexander , Индикаторы, может, и рисуют графики по стаканам - никогда не пользовался ни тем, ни другим, ни третьим. Как, кстати, и поддержкой с сопротивлением. А все решения на покупки-продажи принимаются только роботом. Когда-то я пытался с ним соревноваться, но позорно проиграл. Да, и скрипт один-единственный на все случаи жизни.
На каком принципе основан Ваш робот если не секрет конечно? Я прошу написать без подробностей и нюансов, а просто на пальцах для понимания сути. Ведь на основании чего-то же он срабатывает? Чего? Понятное дело, что в 2-х словах весь алгоритм описать сложно, но всё же... Можно намекнуть без секретов? Хотя бы понять в чём идея алгоритма?
nikolz написал: это Вы велосипед изобрели, называется индикатор "аллигатор"
Нет. У меня абсолютно совершенно другое. К аллигатору никакого отношения и близко не имеет. Аллигатор, тот анализирует прошлое, т.е. прошлые свечи для построения 3-х скользящих на разных периодах, каждая из которых имеет свой сдвиг вперёд на своё количество. Я вообще свечи игнорирую и у меня 2-е кривых, данные из реального времени - построение кривых в момент прихода свечи без её анализа, в расчёте только данные из стакана, т.е. я за точку отсчёта просто беру приход свечи и считаю стакан в обоих направлениях.
nikolz написал: это Вы велосипед изобрели, называется индикатор "аллигатор"
Нет. У меня абсолютно совершенно другое. К аллигатору никакого отношения и близко не имеет. Аллигатор, тот анализирует прошлое, т.е. прошлые свечи для построения 3-х скользящих на разных периодах, каждая из которых имеет свой сдвиг вперёд на своё количество. Я вообще свечи игнорирую и у меня 2-е кривых, данные из реального времени - построение кривых в момент прихода свечи без её анализа, в расчёте только данные из стакана, т.е. я за точку отсчёта просто беру приход свечи и считаю стакан в обоих направлениях.
Вы не учитываете то, что свеча и стакан асинхронны. Кроме того стакан приходит измененными позициями. Понятие "реальное время" условно. Обычно под ним понимают время реакции на событие Т е если до следующего события Вы успеваете отреагировать на предыдущее то это реальное время. ------------------- В итоге Вы что-то строите по заявкам в стакане. Как вы удостоверились что по этому индикатору Вы торгуете прибыльно.
nikolz написал: Стакан - это и есть прогноз будущего, та как в нем заявки - т е заявки на сделки в будущем с горизонтом в мс, так как через мс-сек стакан уже другой.
В части того, что прогноз будущего - да, без прогноза заявку вообще никто не делает, ни робот, ни человек, а вот в части того, что с горизонтом в мс - нет. Это так кажется, что стакан быстро и динамично меняется. Меняется то он меняется, быстро меняется в основном его часть, которая на стыке bid-offer, остальная часть стакана намного более статична и эти статичные части в bid и в offer просто скользят по стакану вверх-вниз. А вот следить надо не за быстроменяющейся частью стакана, а именно за более статичными. От того как они меняются и в каком направлении, от того и зависит тренд. Эта их бОльшая относительная статичность никакие не миллисекунды, она минуты длится, а то и в переделах пол часа - час. Когда сопротивляются повышению цены - в стакан прям начинают заваливать заявками на продажу с крупными объёмами, как натиск спадает, так и заявки такие резко уходят из стакана, тоже самое и в отношении поддержки, не дают цене уйти вниз своими крупными заявками. Но тут надо учитывать не только перевес одних над другими, но и общие объёмы и тех и тех, и объём торгов, и пару графиков сразу, а не только скажем фьючерса, нужно учитывать и изменение базы. Да и вообще интересно смотреть как меняются стаканы во времени того же фьючерс например относительно базы.
nikolz написал: Стакан - это и есть прогноз будущего, та как в нем заявки - т е заявки на сделки в будущем с горизонтом в мс, так как через мс-сек стакан уже другой.
В части того, что прогноз будущего - да, без прогноза заявку вообще никто не делает, ни робот, ни человек, а вот в части того, что с горизонтом в мс - нет. Это так кажется, что стакан быстро и динамично меняется. Меняется то он меняется, быстро меняется в основном его часть, которая на стыке bid-offer, остальная часть стакана намного более статична и эти статичные части в bid и в offer просто скользят по стакану вверх-вниз. А вот следить надо не за быстроменяющейся частью стакана, а именно за более статичными. От того как они меняются и в каком направлении, от того и зависит тренд. Эта их бОльшая относительная статичность никакие не миллисекунды, она минуты длится, а то и в переделах пол часа - час. Когда сопротивляются повышению цены - в стакан прям начинают заваливать заявками на продажу с крупными объёмами, как натиск спадает, так и заявки такие резко уходят из стакана, тоже самое и в отношении поддержки, не дают цене уйти вниз своими крупными заявками. Но тут надо учитывать не только перевес одних над другими, но и общие объёмы и тех и тех, и объём торгов, и пару графиков сразу, а не только скажем фьючерса, нужно учитывать и изменение базы. Да и вообще интересно смотреть как меняются стаканы во времени того же фьючерс например относительно базы.
То что Вы видите как правило специально создает крупный игрок либо маркет-мейкер. Например, чтобы продать свою позицию крупный игрок вынужден гнать рынок вверх, чтобы увлечь толпу на покупку его позиции В итоге буратино на вершине, а рынок катится вниз. и наоборот.
nikolz написал: Именно по стакану и работают HFT роботы. Но горизонт их прогноза -здесь и сейчас.
Может HFT так и работают. У меня нет тенденции словить что-то в малых диапазонах времени. Как и описал выше тенденция она нарастает со временем, длится не мс, а минуты, времени для принятия решения предостаточно. А игратся в пределах миллисекунд, так там такое изменение цены маленькое будет на купил-продал или наоборот, что и комиссии брокера не оправдает.
Автоматический робот с сотнями заявок и сделок в день это может и хорошо, но я не маркет-мейкер, у меня нет такой ликвидности, не могу совершать сделки на миллисекундах и комиссии брокер берёт и биржа не как с маркет-мейкера с меня.
Alexander, Ну, во-первых, принципов там гораздо больше одного. Срабатывает он по разным причинам. В частности, работа на срочном и на фондовом рынке весьма заметно отличается. Поведение алгоритма зависит не только от текущего поведения рынка, но и от состояния портфеля и кошелька. Один из критериев базируется на предположении, что рынок обладает инерцией (стоящий курс нелегко разогнать, движущийся нелегко остановить), другой на том, что сороконожка более устойчива, и тикеров в портфеле должно быть уж никак не меньше десяти. Третий - что поведение рынка на разных таймфреймах может заметно отличаться - он может торговать сразу на нескольких. Четвёртый - что любые индикаторы с предсказаниями движения курса время от времени врут, в т.ч. с точностью до наоборот, поэтому гаданиями на кофейной гуще заниматься не следует. Пятый учитывает ликвидность тикера, шестой - волатильность, седьмой - дороговизну (затраты на покупку одного лота), восьмой - отклонение текущего значения курса от последней свечи таймфрейма, девятый - скорость движения курса (разность последней и предпоследней свечи), десятый...
nikolz написал: Как вы удостоверились что по этому индикатору Вы торгуете прибыльно.
С учётом того, что написал выше, удостовериться просто. У меня всего несколько сделок в день, а не сотни. Заявку по тренду, обратная заявка выставлюяется с прибылью если робот, сработала - прибыль есть. Если вручную, то и так вижу что закрываю обратной заявкой.
Alexander написал: Автоматический робот с сотнями заявок и сделок в день это может и хорошо, но я не маркет-мейкер, у меня нет такой ликвидности, не могу совершать сделки на миллисекундах и комиссии брокер берёт и биржа не как с маркет-мейкера с меня.
Дело в том, что если Вы используете данные которые медленно меняются , что Вы обнаруживаете именно по истории их изменения, т е по прошлому, то совершаете редко сделки то вы должны уметь прогнозировать на интервал периода Вашего наблюдения. ---------------------- проще говоря, чем реже Вы делаете сделки тем больше должен быть горизонт прогноза. Поэтому либо вы используете HFT торгуете быстро и интервал прогноза маленький либо наоборот. ------------------ Не надо изобретать велосипед не изучив существующие конструкции велосипедов.
nikolz написал: Вы не учитываете то, что свеча и стакан асинхронны. Кроме того стакан приходит измененными позициями.Понятие "реальное время" условно. Обычно под ним понимают время реакции на событиеТ е если до следующего события Вы успеваете отреагировать на предыдущее то это реальное время.
Мне и не надо полного синхронизма. У меня диапазон времени в пределах минут как писал выше. Если робот, то просто ждёт когда появится нужный "большой" разрыв (если судить по графику) и чтобы были соответствующие минимальные объёмы. Если вручную, то визуально смотрю на графики и сам принимаю решения, что "пора" выставить заявку.
Владимир написал: Alexander, Ну, во-первых, принципов там гораздо больше одного. Срабатывает он по разным причинам. В частности, работа на срочном и на фондовом рынке весьма заметно отличается. Поведение алгоритма зависит не только от текущего поведения рынка, но и от состояния портфеля и кошелька. Один из критериев базируется на предположении, что рынок обладает инерцией (стоящий курс нелегко разогнать, движущийся нелегко остановить), другой на том, что сороконожка более устойчива, и тикеров в портфеле должно быть уж никак не меньше десяти. Третий - что поведение рынка на разных таймфреймах может заметно отличаться - он может торговать сразу на нескольких. Четвёртый - что любые индикаторы с предсказаниями движения курса время от времени врут, в т.ч. с точностью до наоборот, поэтому гаданиями на кофейной гуще заниматься не следует. Пятый учитывает ликвидность тикера, шестой - волатильность, седьмой - дороговизну (затраты на покупку одного лота), восьмой - отклонение текущего значения курса от последней свечи таймфрейма, девятый - скорость движения курса (разность последней и предпоследней свечи), десятый...
Да, сложный у Вас робот. Каа Вы пишите - единственный на все случаи жизни, его постоянно совершенствуете? Алгоритм меняется? Данные меняете? Не может же он быть универсальным.
Alexander, Менял я его довольно долго - пару лет. Фондовый рынок не меняю уже несколько месяцев - устраивает буквально всё, а срочный, относительно новый для меня, последний раз менял где-то неделю назад. Пока что тоже всё устраивает. Ну и, поскольку вручную я давно уже не торгую, алгоритм получился очень даже универсальным.
nikolz написал: То что Вы видите как правило специально создает крупный игрок либо маркет-мейкер.Например, чтобы продать свою позицию крупный игрок вынужден гнать рынок вверх, чтобы увлечь толпу на покупку его позицииВ итоге буратино на вершине, а рынок катится вниз.и наоборот.
Не совсем так. Хотя и так конечно тоже. Я это не отрицаю, что так крупняк работает. Но он после этих манипуляций рыночную цену существенно двигает по итогу, я же стараюсь ловить зарождение любого тренда, в том числе и крупного игроке, не важно, и не держу позицию, как буратины, а быстро её сливаю, т.е. ловлю более менее не такие существенные разрывы в цене, а стараюсь словить более мелки колебания в течении дня. Если он показывает, что двигает рынок вверх для продажи, мне надо поймать его тренд на повышение, а потом по-любому будет отскок вниз(мини-коррекция), вот на ней мне и надо продать, и пусть этот рынок хоть куда потом идёт, хоть вверх его гонят, хоть вниз. В основном стараюсь работать на малой волатильности.