DARK написал: 1-е нужно узнавать есть ли открытые позиции(любые) if()
В зависимости от рынка, это либо функция getDepoEx (таблица лимитов по бумагам) для фондового, либо getFuturesHolding (таблица позиций по счетам) для срочного рынка. Для денег соответственно getMoneyEx (лимиты по деньгам) либо getFuturesLimit (ограничения по счетам). Еще есть таблицы Клиентский портфель (getPortfolioInfoEx) и купить/продать (getBuySellInfoEx) Проще всего понять что Вам нужно, это посмотреть в интерфейсе терминала QUIK и далее уже искать нужное поле в документации на Lua.
Цитата
DARK написал: 2-е нужен пример(код) Получить значение Open для указанной свечи (цена открытия свечи) Получить значение High для указанной свечи (наибольшая цена свечи) Получить значение Low для указанной свечи (наименьшая цена свечи) Получить значение Close для указанной свечи (цена закрытия свечи) Получить значение Time для указанной свечи (время открытия свечи )
В зависимости от логики которую Вы хотите заложить в код, это либо функция getCandlesByIndex, либо CreateDataSource. У каждой свои нюансы, смотреть документацию QLUA.chm.
Цитата
DARK написал: 3-е как отправить заявку на покупку, продажу, как отправить стоп ордера, и как отправлять лимитные ордера.(код)
Для этого есть функция sendTransaction. Параметры транзакций точно такие же как для tri файлов (см документацию на терминал).
Если текущее время QUIK сервера, то через функцию getInfoParam. Если МБ (а это НЕ тоже самое что время сервера QUIK) то надежно никак. Время МБ в чистом виде в QUIK нигде не транслируется. Выход, либо синхронизировать время Вашего компьютера со временем биржи, либо смотреть на время в таблице обезличенных сделок или таблице текущих торгов (время последнего изменения).
Николай Камынин, Ваш пример не работает на пустых интервалах. Собственно это есть цель данной ветки форума, о чем и был мой пример выше, а не о том как считать SMA. Ваш же пример на пустых интервалах сразу же ломается. Не говоря уже о том что Ваш индикатор рисует нулевую свечку в начале, да и вообще значения индикатора от чего-то больше оригинальных (сравните со встроенном SMA). В общем не то.
Settings = { Name = "*nk_SMA", Period = 9, line = {{Name = "SMA",Type = TYPE_LINE, Color = RGB(255, 0, 0)}} }
local SUM,i_,SMA,m=0,0,0,0; function Init() return #Settings.line end
function OnCalculate(I) if I == 1 then SUM=0; i_=0; SMA=C(I);m=0; end if I~=i_ then if m>Settings.Period then m=Settings.Period; if C(i_-m) then SUM-C(i_-m) end end if C(I) then SUM_TMP=SUM +C(I); m=m+1; SMA=SUM/m; end end i_o=I; end return SMA; end
помогите исправить ошибку attempt to index field(a nil value), при запуске скрипта если стакан не полный то вылезает ошибка attempt to index field(a nil value)
Вячеслав написал: Строчка, которую Вы написали, полностью совпадает с моей кроме кавычек. Наверное что то не вижу.
Вот именно. кавычки - это строковое значение, а без кавычек это переменная которая меняет значения. Вам не кажется что брать свечки с одного графика, по количеству свечек с другого, как-то не правильно? А ведь именно это Вы и делаете в строке getCandlesByIndex("RSI", 0, RSI-3, 2). Значение "RSI" (в кавычках) - это строка и она НЕ меняется. А RSI (без кавычек) - это переменная которая меняется в цикле local RSI=getNumCandles(chart[i])
помогите исправить ошибку attempt to index field(a nil value), при запуске скрипта если стакан не полный то вылезает ошибка attempt to index field(a nil value)
Здравствуйте, Если Вы перебираете идентификаторы, то и в getCandlesByIndex тоже надо их перебирать. т.е. напишите так: RSI_t,RSI_n,RSI_i=getCandlesByIndex(RSI, 0, RSI-3, 2)
Если нужен дальнейший анализ, приведите полный код и укажите строку на которой возникает ошибка (написано в тексте ошибки)
Егор Масалкин, Пришлите нам для анализа архив всей папки с терминалом QUIK (без ключей доступа) на адрес quiksupport@arqatech.com. Архив следует паковать при закрытом терминале. Если файл архива получится больше 10мб, заархивируйте его с паролем и выложите на какой-либо файлообменник. В письме к нам сообщите ссылку для скачивания, и пароль.
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
s_mike@rambler.ru написал: Однако вторая причина по-прежнему существует. Представьте себе график, состоящий из одной свечи. Первый день торговли фьючерсом на дневном графике. Или первая неделя на недельном графике. Нам же может захотеться посмотреть например, объемы покупок и объемы продаж за этот день или за неделю соответственно? Может захотеться.
Кажется я понял, Вам надо вычесть из текущего значения графика, его значение на начало торгов текущего дня? Нет проблем, делаем такую же, временную таблицу как с индексами, только вместо индексов считаем изменения (тики). Будет тоже самое что индексы.
s_mike@rambler.ru написал: А вот индикатор, который посчитает и нарисует объемы покупок и продаж, построенный на таком графике, состоящем из одной свечи, сойдет с ума - он будет на каждом тике считать, что начался новый перерасчет.
Все равно не вижу проблем. На недельном графике, Вы в любом случае, не увидите объем за день, не говоря уже об объемах на покупку и на продажу. Никакой true/false тут не поможет. И потом, если обнулять переменные при Index==1, то в случае графика с одной свечой, всегда будет происходить расчет с нуля, как будто первый раз запустили. Никто с ума не сойдет.
Цитата
s_mike@rambler.ru написал: Да и вообще. Такая проверка - самый натуралный официально признанный костыль.
Приведите реальный пример индикатора, когда это работает не как надо.
Речь о том, что вместо: Out = func(i, {Period=SP, Metod = M, VType="Close"}, ds)
можно писать так: Out = func(i, {Period=SP, Metod = M, VType="Any"}, {[i] = C(i)})
Но надо помнить, что если в индикаторе, требуются значения предыдущих свечей, то надо их указать, например так: Out = func(i, {Period=SP, Metod = M, VType="Any"}, {[i] = C(i), [i-1] = C(i-1)})
при этом VType надо указать именно "Any", а если надо "Typical", то указать его через функцию Value, например так: Out = func(i, {Period=SP, Metod = M, VType="Any"}, {[i] = Value(i,"Typical",ds)})
s_mike@rambler.ru написал: При написании индикатора на языке луа невозможно отследить момент полного перерсчета индикатора.
Момент полного перерасчета, это Index==Size(). Дальше, идет уже текущее обновление. Или речь не про полный перерасчет, а про начало расчета? Тогда это Index==1.
Цитата
s_mike@rambler.ru написал: Свеча с номером 1 может быть пустой и колбек oncalculate на ней никогда не вызовется
Это не правда, Вызовется, еще как. Если конечно речь про последние версии терминала.
Цитата
s_mike@rambler.ru написал: Способ сравнения номера свечи с 1 проблему не решает. Свеча с номером 1 может быть пустой и колбек oncalculate на ней никогда не вызовется. Также ничто не мешает графику состоять просто из одной свечи - в этом случае " полный перерасчет" будет на каждом тике.
Не вижу тут каких-либо проблем. И не могу вспомнить ни одного индикатора, где с этим были бы какие-либо сложности.
Роман, Кто сказал что срезы идут раз в 1мс? Это возможный минимум, которого добиться ой как не легко. В действительности, все куда хуже, срезы могут идти и раз в несколько секунд, все зависит от настроек на стороне брокера и его инфраструктуры. Посмотрите сами, по таблице обезличенных сделок, как часто едут тики по индексу именно у Вашего брокера. Если есть какая-то задержка, это повод обратиться к брокеру заявив о проблеме.
Let_it_go написал: Не происходит ли тут лишних действий, всё ли экономно в плане получения и подсчёта индикаторов?
Происходит. Например не понятно, зачем Вам две функции DataSource и DataSource_minutes. В чем смысл, ведь они делают одно и тоже? Далее, для индикатора RSI() не обязательно передавать в функцию весь ds целиком, достаточно только предыдущее значение (i-1) и текущее. А для индикатора SD() только текущее (ds_minutes[sec]:Size()).
Никаких особенностей, кроме того что параметры разные, нет. Совет тот же, проверьте что попадает в параметры функции и визуально проверьте что в таблице.
Let_it_go написал: надо ли заводить вторую таблицу типа ds?
Это зависит от того что вы будете дальше делать с данными. Если Вам нужно дальше работать с источником ds то да надо создавать отдельный ds, если нет, то нет.
Здравствуйте, Если код клиента у Вас один, то в транзакции его указывать не обязательно, сервер сам его подставит. Если у Вас несколько кодов клиента, то требуется в транзакции явно указать какой нужно использовать. Сейчас же у Вас в транзакции вообще отсутствует параметр указывающий какой код клиента использовать. Добавьте в таблицу transaction параметр CLIENT_CODE по аналогии с остальными, в котором укажите нужный код клиента.
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
V Y написал: Я правильно понял, что в скрипте функция onAllTrade вернет мне информацию только по тем бумагам которые присутствуют в открытой в данный момент в терминале таблице (таблицах) обезличенных сделок?
OnAllTrade возвращает информацию об обезличенных сделках, по тем бумагам, по которым Вы эту информацию закажите. И совершенно не важно как именно произойдет этот заказ. Через открытие таблицы, тиковый график или через CreateDataSource с интервалом INTERVAL_TICK
О каком рынке Вы говорите? Если о срочном, то там вообще код клиента как таковой не используется, туда можно писать что угодно. На срочном рынке играет роль счет депо.
green_X5, Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Андрей Митрофанов, Посмотрите в интерфейсе терминала QUIK где находится нужная Вам цифра, и далее уже исходите из этого. getMoney служит для получения данных из таблицы лимитов по деньгам. getFuturesLimit служит для получения данных из таблицы ограничений по клиентским счетам.
Добавить флаг на первый запуск функции Run. Перед вызовом SetUpdateCallback делаем его true, а в конце функции Run делаем false. В функции Run проверяем, если флаг true, значит это первое срабатывание. Если срабатывание первое, и пришедший индекс не первый, то делаем getCandlesByIndex от 1 до getNumCandles свечей. Полученные свечки обрабатываем в цикле. Таким образом, если первой пришла не первая свечка, то случится обработка пропущенных свечек.
Судя по коду, Вы ожидаете что в функции Run появятся все свечи с первой по последнюю. Однако туда попадают только свежие обновления. Так и должно быть, т.к. график по заказанному параметру у Вас открыт и информация не будет заказываться повторно. В связи с чем и пропущенные свечки в колбек не придут.
Если нужны пропущенные свечки, пройдитесь циклом от 1 до ds:Size()
Возможные значения описаны в описании параметров таблицы. Цитата от туда Тип лимита. Возможные значения: «0» – не определён; «1» – основной счет; «2» – клиентские и дополнительные счета; «4» – все счета торг. членов
Егор Масалкин написал: Все значения FIRM_ID, ACCOUNT и SECCODE соответствуют полям "Фирма", "Торговый счет" и "Код класса" таблицы "Позиции по клиентским счетам".
green_X5 написал: Сергей, попробую проще изложить задачу. Нужно в скрипте работать с МА фьючерса и видеть её (МА) на графике. Меняем значение МА - видим эти изменения на графике и теперь скрипт работает с МА с новыми настройками. Где менять параметры МА - в скрипте или в наложенном индикаторе на график - мне всё равно, будет одинаково удобно.
С этого и нужно было начинать. Тогда правильный вариант 1:
Цитата
green_X5 написал: 1. Накладываем на график индикатор из папки LuaIndicators, подписываемся на свечки этого графика, и создаем в своем скрипте колбэк на изменение свечек, по колбэку читаем значение наложенного MA .
Но Вы говорите что есть проблема:
Цитата
green_X5 написал: Это я пробовал, работает. Но есть проблема, при старте скрипта указанная выше строчка не срабатывает, а вот на последующих вызовах колбэка уже нормально.
Надо разбираться почему не работает и что именно не работает. Приведите пример кода и последовательность действий.
К слову, есть еще один вариант - вообще всю логику перенести в скрипт индикатора, если это допустимо.
green_X5 написал: Прошу дать вариант решения задачи. Спасибо.
Какой задачи? Вы пишите только свои действия, а зачем это все не пишите. Все выше сказанное не несет смысла. Зачем делать в обычном скрипте то, что с легкостью делается в индикаторах? О какой синхронизации "МА - на графике и в скрипте" идет речь? Зачем Вам вообще понадобился getCandlesByIndex, если в индикаторах есть OnCalculate? Вы в индикаторе получили изменения цены, посчитали индикатор, все. Дальше делайте с этими цифрами что угодно.
Зачем это делать из обычного скрипта? Для этого существуют скрипты Lua индикаторов. В обычном скрипте, единственное что можно рисовать на графиках, это метки.
green_X5 написал: А вне main никак не подписаться, чтобы упаковать подписку в отдельную функцию с вызовом не из main?
Проблема изучается. Постараемся в ближайшее время дать ответ.
Цитата
green_X5 написал: И второй вопрос, попроще. Для подписки (с целью затем запустить колбэк на изменения) на котировки инструмента по классу и коду есть функция CreateDataSource. А можно создать колбэк на изменение индикатора, например EMA, наложенного на тот же график? Понятно, что выход есть - подписываемся на свечки, и по колбэку считываем EMA. А вот колбэк на непосредственно EMA возможен? Ведь он будет срабатывать гораздо реже, только раз в таймфрейм графика, если например EMA по Open.
Для решения задачи, Вы можете добавить функцию расчета EMA на данных из CreateDataSource. Будет тоже самое. Функции уже выкладывались тут https://forum.quik.ru/forum17/topic1157/
s_mike@rambler.ru, Кажется я Вас понял, вопрос не в том как поменять значение на 5й свечке, когда текущая 10я. а в том как поменять значение на 10й свечке, если текущая только 5я, при условии что мы не знаем, существует ли она вообще. Вариантов несколько: 1) проверять свечки в будущее. (по производительности не очень.) 2) рисовать данные именно на 10й свечке.
2й вариант куда разумней и быстрее. Ничего не мешает запомнить цифру на 5й свече, но нарисовать только когда дело дойдет до 10й. Примерно так и реализовано на линии Chinkou, дальше уже идут вариации, как это оптимальней всего сделать. Если у вас есть свои идеи, готов выслушать.
s_mike@rambler.ru написал: таким образом, ваш принцип состоит из трех идей. 1. всегда рассчитываем свечи по порядку их следования 2. строим буфер исходных данных с фильтрацией пропусков 3. строим буфер рассчитанных данных с фильтрацией пропусков. для простейших индикаторов подходит.
1. да 2. да, только не "буфер исходных данных", а номера индексов (Index_tbl). 3. да, но не во всех индикаторах это необходимо.
Цитата
s_mike@rambler.ru написал: теперь берем что-то посложнее типа зигзага. вопрос таков. необходимо изменить значение в свече с номером size()-k, где k есть вычисляемое значение. как с этим будете бороться? третий буфер вводить?
если проще, интересует уже сдвиг "влево"? Если так то в том же Ichimoku, на линии Chinkou, для этого используется функция SetValue.
s_mike@rambler.ru написал: Сергей, а давайте чуточку усложним. Сделаем сдвиг этого SMA индикатора на N свечей вправо Как это сделано например в одной из линий индикатора ишимоку. Для простоты пусть N будет фиксированным параметром.
"вправо"? это легко, с тем ограничением что свечки "в будущее" к сожалению строить нельзя. не поверите но куда сложнее "влево" В том же Ichimoku, линии Senkou, у меня запоминаются в отдельную таблицу, но выводятся не в текущем их значении, а в прошлом (со сдвигом) В старых примерах индикаторов на Lua это видно, в новых будет также.
Про возможность рисовать индикаторы в будущее, уже было зарегистрировано пожелание, оно пока еще не реализовано.
Русский написал: Не могли бы Вы подсказать, как таблицей (вместо цикла) посчитать количество непустых свечей?
А в чем сложность с таблицей Index_tbl? Вопрос чисто синтаксиса Lua, что описано в документации на Lua. К индикаторам вопрос не имеет отношения.
В примере, Index_tbl по порядковому номеру, выдаст настоящий номер свечки. Надо общее количество свечек, пожалуйста #Index_tbl Надо пробежать по непустым свечкам, делается через for i=1, #Index_tbl do
Здравствуйте, 1) Через LUA загружать лимиты нельзя. Для автоматизации загрузки лимитов, есть отдельное ПО FillLimits. Или для автоматизированных систем отдельное API QuikLimit.
2) только если прикрутить к скрипту WinApi, но это на Ваш страх и риск и мы это не поддерживаем.