RC2 написал: В целом мне необходимо реализовать трейлинг-стоп, но без выставления заявки, т.е расчет трейлинг-стопа должен быть в скрипте. На сколько я понимаю это не сделать без сохранения цен во внешний файл, т.к. между итерациями все переменные обнуляются.
не определяйте переменные как локальные и они не будут обнуляться. Использовать запись в файл для реализации трейлинг-стопа нет необходимости.
Если быть точным, то сложение двух свечей и вычитание из суммы одной. На самом деле это азбука цифровой обработки сигналов в скользящем временном окне.
swerg пишет: Если же надо просуммировать 1000 свечей, да еще дифур решить для вычисления значения индикатора - лучше взять готовое значение из квика, если там есть такой индикатор, это и проще и надёжнее, ибо в своём алгоритме мы еще и наошибаться можем, а квиковый индикатор - хотя бы глазами видишь что он на самом деле считает.
Вот тут у Вас ошибочка Чтобы сложить 1000 свечей надо столько же время сколько для сложения двух. --------------------------------------- Вопрос же поставленный в начале вообще то не имеет однозначного решения Он из разряда "Как стать счастливым"
У меня ошибки нет, а вот вы - обманываете. Чтобы сложить 1000 свечей - требуется по крайней мере 1000 операций сложения. Я понимаю, что вы говорите про количество сложений на каждую свечу и итеративный подход, однако если уж взялись указывать на ошибки другим - будьте любезны и сами быть в этой ситуации непогрешимым в формулировках. Иначе, сами понимаете, лужа за углом может поджидать.
нет, я говорю о работе в реальном времени. В реальном времени циклы - это зло и их в правильных алгоритмах не применяют. Поэтому складывать надо текущую сумму с новым значением т е сложение двух свечей.
Николай Камынин написал: ff1(-8.8) Все работает правильно.
Вопрос был в другом
Код
function ff1 (dp)
for i = - 8.8 , - 0.8 do
if dp = = i then print (dp) end
end
end
for param, value in pairs({ - 8.8 , - 7.8 , - 6.8 , - 5.8 , - 4.8 , - 3.8 , - 2.8 , - 1.8 , - 0.8 }) do
ff1(value)
end
Я Вам про это и ответил. В данном варианте Вам надо написать функцию так: unction ff1(dp) for i=-8.8,-0.8 do print(i.."/"..dp) if string(dp)==string(i) then print(dp) end end end
а если передать строку: ff1(tostring(-8.8)) То получим: ------------------ -8.8/-8.8 -7.8/-8.8 -6.8/-8.8 -5.8/-8.8 -4.8/-8.8 -3.8/-8.8 -2.8/-8.8 -1.8/-8.8 -0.8/-8.8 >Exit code: 0 Т е строка -8.8 не равна числу -8.8. Это тоже правильная работа if .
сравнивать можно, но важно, чтобы тип у сравниваемых переменных был одинаковый. Так как тип указан неявно, то может возникать ситуация сравнения числа с текстом. поэтому при сравнении указывайте тип явно.
Космонавт написал: Добрый день. У меня робот мониторит больше сотни акций, по всем открыты графики. Это не праздный вопрос, а злободневный. Что продуктивнее - получать данные индикатора с графика через getCandlesByIndex или НЕ открывать графики и всё делать через заказ данных с помощью DataStore, а индикаторы считать внутри робота? 1. Что быстрее? 2. Что экономнее для ресурсов компьютера?
Спасибо.
Для большого числа акций делаю так: Получаю ТВС по подписке , в реале (налету) сортирую по инструментам и формирую необходимые индикаторы. Так как обработка делается в реале, то затраты ресурсов минимальные.
Vladimir написал: А если оперативки 8 ГБ, есть ли разница? Quik же бывает только 32битный, т.е. не может использовать всю память? Т.е. вопрос: можно ли на нем развертывать большие проекты на клуа с сотней ботов?
Размер оперативки - в QUIK-е - влияет лишь на количество одновременно открытых окон и то, до определённого предела. Как уже говорил - QUIK - относится к системам с обязательной сериализацией данных. То есть, любой "чих" пользователя, а также ЛЮБОЕ изменение в принимаемых и отправляемых транзакциях - он сериализует на ДИСК. Потому что биржевые данные - это реальные деньги. Отсюда и то, что он даже не сжимает данные при хранении на диске - потому что так быстрей.
Про сериализацию это конечно хорошо, но когда КВИК зачинали, это слово не применялось. В квике использованы проецируемые в память файлы - это основной метод винды для работы с большими массивами.
Николай Камынин написал: надо знать лишь две свечи в MA и одну в EMA.
Это если есть результаты предыдущих вычислений. А если они ==0, то не получится.
Это лишь в начале т е при запуске. но в это время данные поступают с сервера и они рассчитываются в реальном времени. И условия остаются теже - не более двух свечей.
действительно, какая-то каша. На самом деле, скорость вычисление скользящих не зависит от числа свечей , фактически для этого надо знать лишь две свечи в MA и одну в EMA. Просто надо изучить цифровую обработку сигналов.
Ivanco написал: Подскажите пожалуйста, возможно ли средствами языка QLUA делать какие-либо графические отметки на графике инструмента в QUIK? Например, если алгоритм находит удачный момент для сделки - ставить графическую отметку на графике и т.п.
Заранее благодарен.
Функции для работы с метками Предназначены для построения меток и установки их на графике.
AddLabel - добавляет метку с заданными параметрами
Теоретическая разница получения данных CreateDataSource+SetUpdateCallback или getNumCandles()+getCandlesByIndex(), В чем разница получения данных 1 способом и 2 способом
Владимир Б****ов написал: Теоретически, по времени, есть разница между колбэком и таймером (sleep()), а практически разница заметна? может кто проводил измерения/исследования?
колбек и sleep() - это две большие разницы. колбек - это функция LUA , которую вызывает терминал QUIK для обработки события. sleep() - это остановка исполнения потока(процесса) и досрочное освобождение процессора.
Теоретическая разница получения данных CreateDataSource+SetUpdateCallback или getNumCandles()+getCandlesByIndex(), В чем разница получения данных 1 способом и 2 способом
Теоретическая разница получения данных CreateDataSource+SetUpdateCallback или getNumCandles()+getCandlesByIndex(), В чем разница получения данных 1 способом и 2 способом
Николай Камынин написал: CreateDataSource+SetUpdateCallback - получаем данный в момент прихода их с сервера,
Т.е если таймфрейм установлен в 3 минуты - то получение данных ~ 1 раз в 3 минуты, т.е. объективную информацию по последней свечке(текущей) мы не знаем, знаем только по предпоследней?
нет не так. Будут приходить тики, которые отображаются как close не закрытой свечи. Т е фактически вне зависимости от тайма Вы будете получать тики.
Теоретическая разница получения данных CreateDataSource+SetUpdateCallback или getNumCandles()+getCandlesByIndex(), В чем разница получения данных 1 способом и 2 способом
Разница в следующем: ------------------------------------ CreateDataSource+SetUpdateCallback - получаем данный в момент прихода их с сервера, т е до помещения в хранилище в терминале. т е один раз, в момент поступления в терминал. ------------------------------------------ getNumCandles()+getCandlesByIndex() - читаем данные из хранилища. Сколько угодно раз после поступления в хранилище терминала.
В системах реального времени используется Watchdog. Это таймер, который необходимо перезапускать через время, меньшее, чем его срабатывание. Если его не перезапустили, то он вызывает прерывание и начинает посылает сообщения об ошибке. Если его вовремя кормят, то он молчит. Можете применить такой же способ.
Тогда при таком требовании, Вы должны отдавать себе отчет в том, что когда программа выжрет всю оперативку (а при наличии на машине ее меньше 4Г это случится очень быстро) вся система просто встанет колом.
...
А если оперативки 8 ГБ, есть ли разница? Quik же бывает только 32битный, т.е. не может использовать всю память? Т.е. вопрос: можно ли на нем развертывать большие проекты на клуа с сотней ботов?
Большой проект с сотней роботов невозможно развертывать в QLUA . По двум причинам - медленность VM LUA и медленная реакция QUIK. При сотнях роботов надо использовать многопоточность, API C for LUA, и выделенные сервера. При использовании API C нет проблем задействовать любой объем оперативной памяти.
Когда не было в квике луа решал эту задачу на avtoit. Сейчас это делается с помощью winAPI в LUA , используя модуль Alien. Если умеете писать на СИ, то с помощью API C for LUA. .
проблема в том, что на компе нет библиотек, которые есть на компе разработчика. проверьте свою dll на зависимости на компе разработчика и пользователя. Потом установите у пользователя недостающие библиотеки среды разработчика. обычно это делается через манифест. читайте у майкрософт.
помогите исправить ошибку attempt to index field(a nil value), при запуске скрипта если стакан не полный то вылезает ошибка attempt to index field(a nil value)
Роман написал: s_mike@rambler.ru - визжишь ты, сливая деньги на счете. Тебе написали что вопрос не в программирование, а в алгоритме запуска скрипта!
Вот так поедешь в отпуск, а на бирже очередной сбой, график косой, скрипт запрашивает Клоз, а его нет и программа падает и не запускается, а цена идёт против тебя. А ты жопу греешь на солнце не зная об этом. Если бы скрипт запустился следующий раз, то он пошел бы дальше работать оставив ошибку в логе, так как биржа бы исправила косяк.
Sergey Gorokhov - да, это же ваши косяки или косяки биржи - это ошибку вызывают.Как от вас избавишься? Или выпускайте продукт, что бы вообще не одной ошибки не было в нём. А то сидите и рассказываете задним числом как работать надо!
Посмотрите на проблему немного иначе. КВИК , по определению, это программа подачи поручений брокеру. Есть другие способы подачи таких поручений -телефон, бумажный носитель. -------------------------------------- Все , что есть в квике кроме возможности подачи поручений - это бесплатное приложение (Увы, но это юридически именно так). --------------------------------------- Поэтому получается, что никто ничего Вам не должен. --------------------------------------------- Полагаю, что не только Вам хочется, чтобы скрипт работал вечно и без вмешательства. Но увы, реалия такова, что если скрипт написан плохо, то КВИК то квик его закрывает. Так сделали разработчики и это их право. -------------------------------------- Хотите иначе - пишите пожелания, делайте проверки внутри скрипта, ставьте защиту от падения. Ваше право. ----------------------------- Успехов.
Sergey Gorokhov написал: Для решения проблемы не используйте относительные пути при доступе к сторонним файлам.
Там нет относительных путей! Понятно что скрипт доделывать нужно, но одно если он был запущен - то нужно и запускать каждый раз когда загружается квик, а не выключать загрузку скрипта при каком либо сиюминутном сбое! Там х.з. что может быть (биржа мутит как), мы же не можем прописать всё и вся сразу!
так как скрипт без ошибок надо запускать лишь один раз, то Полагаю,что у Вас следующая проблема: ------------------------- Когда Вы запускаете скрипт кнопкой, то в КВИКЕ уже загружены все данные, которые использует Ваш скрипт и он нормально запускается. ------------------------ Потом Вы выключаете КВИК. При следующем запуске КВИКА с включенным скриптом, скрипт начинает работу сразу же при запуске КВИКА, но информация с сервере еще не пришла. В результате Ваш скрипт натыкается на nil и завершает свою работу по ошибке. ------------------------- Вы полагаете, что скрипт был выключен при закрытии КВИКА, а он просто не может возобновить свою работу. ------------------------- В результате Вы опять вынуждены его запускать нажатием кнопки при новом запуске КВИКА. -------------- Верно ?
не совсем то, так как QLUA на основе Lua 5.1 в которой /* @@ LUAI_MAXCALLS limits the number of nested calls. ** CHANGE it if you need really deep recursive calls. This limit is ** arbitrary; its only purpose is to stop infinite recursion before ** exhausting memory. */ #define LUAI_MAXCALLS 20000 /* @@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function @* can use. ** CHANGE it if you need lots of (Lua) stack space for your C ** functions. This limit is arbitrary; its only purpose is to stop C ** functions to consume unlimited stack space. (must be smaller than ** -LUA_REGISTRYINDEX) */ #define LUAI_MAXCSTACK 8000
дополню предыдущий ответ. Полагаю, что такая ситуация не возникает, так как свечи рассчитывает сервер. Поэтому терминал принимает их пакетом . Пропуск внутри пакета невозможен, так как сервер рассчитал пакет свеча за свечой.
При открытии графика все свечки строятся сразу или возможна ситуация что данные по какой то свече не пришли а через пару тиков появились и эта свеча нарисовалась?
Должны всегда строиться сразу, согласно таблицы обезличенных сделок.
Вот слово должны немного смущает. Вопрос возник по следующей причине: В мт5 могут быть получены не все данные, но при появлении новых данных, в индикаторе, есть параметр: prev_calculated (рассчитанных баров ранее) который обнуляется и на следующем тике я проведу расчёт по более полной истории. Здесь у меня ничего подобного нет, поэтому и решил уточнить. В таком случае, если мне нужно в одном индикаторе для расчёта получать данные по разным бумагам, синхронизировав данные единожды, я больше к этому вопросы могу не возвращаться ? или с синхронизацией есть какие-то другие подводные камни ?
Это не так просто как кажется, так как могут быть интервалы в которых нет сделок в одном из инструментов.
Вызов в форме return functioncall называется концевым вызовом. Lua также поддерживает концевой вызов «себя» (или рекурсивный концевой вызов): в этом случае вызванная функция использует стек вызывающей функции. Поэтому количество вложенных концовых вызовов может быть любым. Заметим только, что концевой вызов стирает отладочную информацию о вызывающей функции.
А разве это не верно: Для получения размера стека используйте функцию lua_checkstack. Для вызова из Lua кода на C необходимо иметь в наличии свободной памяти по крайней мере на LUA_MINSTACK позиций стека. LUA_MINSTACK по умолчанию равно 20. Если размера стека не хватает, его можно увеличить функцией lua_checkstack.
Sergey Gorokhov написал: Проверьте настройки терминала меню Система - Настройки - Основные настройки в "Получение данных" установить галку "Исходя из настроек открытых пользователем таблиц" в "Сохранение данных" установить галку "Данные, отражающие текущее состояние и всю историю изменений" и "Получать пропущенные данные"
Спасибо, все появилось.
Цитата
Sergey Gorokhov написал: Все проще, достаточно установить колбек через SetUpdateCallback
Ок, я сделал так:
Код
ds = CreateDataSource ( "SPBOPT" , "RI95000BI6" , INTERVAL_M1, "theorprice" )
lastCandleIndex = ds: Size ()
ds: SetUpdateCallback (ddd)
function ddd (idx)
if idx > lastCandleIndex then
message ( 'Свеча закрылась. Ее цена закрытия Close = ' .. ds:C(idx))
lastCandleIndex = idx
end
end
Но чем предыдущий код отличается от этого:
Код
new = getParamEx ( "SPBOPT" , "RI95000BI6" , "theorprice" ).param_value + 0
if new ~ = last then
message ( "новое значение " .. new)
end
last = new
Выдают они в одно и то же время одно и то же значение. Или я опять в коде с CreateDataSource намудрил? Если посмотреть на график теоретической цены, то на нем нет горизонтальных линий. Лишь экстремумы, правда не с интервалом в 1 минуту.
Т.е. обновление теории на то же самое значение не бывает и я зря вас мучаю? Достаточно просто ждать актуального изменения и работать?
В первом случае Вы получаете все значения. Во втором лишь значения из срезов пришедших в ТТП. Т е во втором случае возможны пропуски.
помогите исправить ошибку attempt to index field(a nil value), при запуске скрипта если стакан не полный то вылезает ошибка attempt to index field(a nil value)
Алекс Лепс написал: Спасибо за вашу помощь, я попробую переделать.
В примере написано две проверки первый if проверяет существования стакана и очереди в нем Циклы делаются по фактической длине очереди У вас циклы делались на фиксированную длину очереди. Примерно так.
помогите исправить ошибку attempt to index field(a nil value), при запуске скрипта если стакан не полный то вылезает ошибка attempt to index field(a nil value)
mm=getQuoteLevel2("SPBFUT","NKZ6") if mm and mm.bit_count and mm.offer_count then ------------------------- local n=mm.bid_count; while n>0 do a0=mm.bid[n].quantity b0=mm.bid[n].price c0=math.ceil(b0*1000000) d0=tostring((c0/1000000)+1) n=n-1; end ------------------------ n=mm.bid_count; while n>0 do aa0=mm.offer[n].quantity bb0=mm.offer[n].price cc0=math.ceil(bb0*1000000) dd0=tostring((cc0/1000000)-1) n=n-1 end -------------------- end ----------------------------------- -примерно так
помогите исправить ошибку attempt to index field(a nil value), при запуске скрипта если стакан не полный то вылезает ошибка attempt to index field(a nil value)
mm=getQuoteLevel2("SPBFUT","NKZ6") if mm and mm.bit_count and mm.offer_count then a0=mm.bid[mm.bid_count-i].quantity <--------ОШИБКА ЗДЕСЬ b0=mm.bid[mm.bid_count-i].price c0=math.ceil(b0*1000000) d0=tostring((c0/1000000)+1) aa0=mm.offer[mm.offer_count-i].quantity bb0=mm.offer[mm.offer_count-i].price cc0=math.ceil(bb0*1000000) dd0=tostring((cc0/1000000)-1) end
А премию за выявленную ошибку? Вот сейчас работаю с SDK на чип , так фирма за каждую выявленную ошибку всем желающим выплачивает 2000$. Вам тоже не мешало бы перенять опыт передовиков.