Чтобы получить доступ к графику(не индикатору) какого-либо инструмента нужно создать источник данных при помощи функции CreateDataSource().
ВАЖНО!!! Для получения новых данных, кроме тех, что уже есть в открытом графике на текущий момент (тем более, если он не открыт), требуется использовать одну из следующих функций: SetUpdateCallback(), или SetEmptyCallback(), о которых будет написано ниже.
Описание функции CreateDataSource()
-- Функция предназначена для создания таблицы Lua и позволяет работать со свечами, полученными с сервера QUIK, а также реагировать на их изменение.
ds, Error = CreateDataSource (class_code, sec_code, interval [, param]);
-- Параметры:
-- class_code - (STRING) код класса, например "SPBFUT"
-- sec_code - (STRING) код бумаги, например "RIZ5"
-- interval - (NUMBER) константа, обозначающая тайм-фрейм графика, например INTERVAL_M5 (полный список: https://quikluacsharp.ru/qlua-osnovy/spisok-konstant-tajm-frejmov-grafikov/)
-- param - (STRING) необязательный параметр. Если параметр не задан, то заказываются данные на основании таблицы всех сделок, если задан – данные по этому параметру, например "BID" (возможные параметры смотрите ниже)
-- Возвращаемые значения:
-- ds - (TABLE) таблица с данными по свечам графика
-- Error - (STRING) строка ошибки в случае неудачной попытки получить доступ к данным (тогда ds будет nil)
-- Если график, к которому нужно подключиться не открыт в терминале, то данные заказываются с сервера, на их получение нужно время,
-- по этому, рекомендуется добавлять вот такое ожидание, прежде, чем обращаться к ds:
-- Ждет, пока данные будут получены с сервера (на случай, если такой график не открыт)
while (Error == "" or Error == nil) and ds:Size() == 0 do sleep(1) end
if Error ~= "" and Error ~= nil then message("Ошибка подключения к графику: "..Error) end
-- Примеры (одновременно можно подключаться к нескольким источникам данных):
ds1 = CreateDataSource("SPBFUT", "RIU3", INTERVAL_M1, "last");
ds2 = CreateDataSource("QJSIM", "SBER", INTERVAL_M1);
ds3, Error = CreateDataSource("SPBFUT", "RIU3", INTERVAL_M1, "bid");
if ds3 == nil then message('Ошибка подключения: '..Error); end; |
Функция CreateDataSource возвращает таблицу QLua с параметрами, получать значения которых можно следующим образом:
local O = ds:O(i); -- Получить значение Open для указанной свечи (цена открытия свечи)
local H = ds:H(i); -- Получить значение High для указанной свечи (наибольшая цена свечи)
local L = ds:L(i); -- Получить значение Low для указанной свечи (наименьшая цена свечи)
local C = ds:C(i); -- Получить значение Close для указанной свечи (цена закрытия свечи)
local V = ds:V(i); -- Получить значение Volume для указанной свечи (объем сделок в свече)
local T = ds:T(i); -- Получить значение Time для указанной свечи (время открытия свечи (таблица datetime))
-- Где i - индекс свечи (от 1 до ds:Size())
local Size = ds:Size(); -- Возвращает текущий размер (количество свечей в источнике данных)
ds:Close(); -- Удаляет источник данных, отписывается от получения данных
ds:SetUpdateCallback(MyFuncName); -- Позволяет задать пользователю функцию обратного вызова для обработки изменившихся свечей, т.е. когда по выбранному в CreateDataSource параметру в терминал поступит новое значение (возможно такое же), автоматически будет вызвана данная функция, в которую будут передан индекс последней свечи графика, а так же добавятся новые данные в таблицу ds
-- Пример функции:
function MyFuncName(index)
message('На '..index..'-й свече объем вырос до '..ds:V(index));
end;
-- Чтобы получать новые данные без использования функции обратного вызова, а просто получать новые данные в ds и брать их оттуда по необходимости существует функция:
ds:SetEmptyCallback(); -- Которая подписывается на получение новых данных |
Списки возможных параметров, используемых в функции CreateDataSource():
Список для АКЦИЙ
"LOTSIZE" -- Размер лота
"BID" -- Лучшая цена спроса
"BIDDEPTH" -- Спрос по лучшей цене
"BIDDEPTHT" -- Суммарный спрос
"NUMBIDS" -- Количество заявок на покупку
"OFFER" -- Лучшая цена предложения
"OFFERDEPTH" -- Предложение по лучшей цене
"OFFERDEPTHT" -- Суммарное предложение
"NUMOFFERS" -- Количество заявок на продажу
"OPEN" -- Цена открытия
"HIGH" -- Максимальная цена сделки
"LOW" -- Минимальная цена сделки
"LAST" -- Цена последней сделки
"CHANGE" -- Разница цены последней к предыдущей сессии
"QTY" -- Количество бумаг в последней сделке
"VOLTODAY" -- Количество бумаг в обезличенных сделках
"VALTODAY" -- Оборот в деньгах
"VALUE" -- Оборот в деньгах последней сделки
"WAPRICE" -- Средневзвешенная цена
"HIGHBID" -- Лучшая цена спроса сегодня
"LOWOFFER" -- Лучшая цена предложения сегодня
"NUMTRADES" -- Количество сделок за сегодня
"PREVPRICE" -- Цена закрытия
"PREVWAPRICE" -- Предыдущая оценка
"LASTCHANGE" -- % изменения от закрытия
"LASTTOPREVSTLPRC" -- Разница цены последней к предыдущей сессии
"MARKETPRICETODAY" -- Рыночная цена
"SEC_FACE_VALUE" -- Номинал бумаги
"SEC_SCALE" -- Точность цены |
Список для ВАЛЮТЫ
"LOTSIZE" -- Размер лота
"BID" -- Лучшая цена спроса
"BIDDEPTH" -- Спрос по лучшей цене
"BIDDEPTHT" -- Суммарный спрос
"NUMBIDS" -- Количество заявок на покупку
"OFFER" -- Лучшая цена предложения
"OFFERDEPTH" -- Предложение по лучшей цене
"OFFERDEPTHT" -- Суммарное предложение
"NUMOFFERS" -- Количество заявок на продажу
"OPEN" -- Цена открытия
"HIGH" -- Максимальная цена сделки
"LOW" -- Минимальная цена сделки
"LAST" -- Цена последней сделки
"CHANGE" -- Разница цены последней к предыдущей сессии
"QTY" -- Количество бумаг в последней сделке
"VOLTODAY" -- Количество бумаг в обезличенных сделках
"VALTODAY" -- Оборот в деньгах
"VALUE" -- Оборот в деньгах последней сделки
"WAPRICE" -- Средневзвешенная цена
"HIGHBID" -- Лучшая цена спроса сегодня
"LOWOFFER" -- Лучшая цена предложения сегодня
"NUMTRADES" -- Количество сделок за сегодня
"PREVPRICE" -- Цена закрытия
"PREVWAPRICE" -- Предыдущая оценка
"CLOSEPRICE" -- Цена периода закрытия
"LASTCHANGE" -- % изменения от закрытия
"PRICEMINUSPREVWAPRICE" -- Разница цены последней к предыдущей оценке
"LASTTOPREVSTLPRC" -- Разница цены последней к предыдущей сессии
"PRICEMAX" -- Максимально возможная цена
"PRICEMIN" -- Минимально возможная цена
"BASEPRICE" -- Базовый курс
"SEC_FACE_VALUE" -- Номинал бумаги
"SEC_SCALE" -- Точность цены |
Список для ОПЦИОНОВ
"LOTSIZE" -- Размер лота
"BID" -- Лучшая цена спроса
"BIDDEPTH" -- Спрос по лучшей цене
"BIDDEPTHT" -- Суммарный спрос
"NUMBIDS" -- Количество заявок на покупку
"OFFER" -- Лучшая цена предложения
"OFFERDEPTH" -- Предложение по лучшей цене
"OFFERDEPTHT" -- Суммарное предложение
"NUMOFFERS" -- Количество заявок на продажу
"HIGH" -- Максимальная цена сделки
"LOW" -- Минимальная цена сделки
"LAST" -- Цена последней сделки
"CHANGE" -- Разница цены последней к предыдущей сессии
"QTY" -- Количество бумаг в последней сделке
"VOLTODAY" -- Количество бумаг в обезличенных сделках
"VALTODAY" -- Оборот в деньгах
"VALUE" -- Оборот в деньгах последней сделки
"WAPRICE" -- Средневзвешенная цена
"NUMTRADES" -- Количество сделок за сегодня
"PREVPRICE" -- Цена закрытия
"PREVWAPRICE" -- Предыдущая оценка
"LASTCHANGE" -- % изменения от закрытия
"PRICEMINUSPREVWAPRICE" -- Разница цены последней к предыдущей оценке
"PREVSETTLEPRICE" -- Предыдущая расчетная цена
"NUMCONTRACTS" -- Количество открытых позиций
"BUYDEPO" -- Гарантийное обеспечение продавца
"SELLDEPO" -- Гарантийное обеспечение покупателя
"BGOP" -- БГО по покрытым позициям
"BGONP" -- БГО по непокрытым позициям
"STRIKE" -- Цена страйк
"STEPPRICET" -- Стоимость шага цены
"STEPPRICE" -- Стоимость шага цены (для новых контрактов FORTS и RTS Standard)
"VOLATILITY" -- Волатильность опциона
"THEORPRICE" -- Теоретическая цена
"CLPRICE" -- Котировка последнего клиринга
"SEC_FACE_VALUE" -- Номинал бумаги
"SEC_SCALE" -- Точность цены |
Список для ФЬЮЧЕРСОВ
"LOTSIZE" -- Размер лота
"BID" -- Лучшая цена спроса
"BIDDEPTH" -- Спрос по лучшей цене
"BIDDEPTHT" -- Суммарный спрос
"NUMBIDS" -- Количество заявок на покупку
"OFFER" -- Лучшая цена предложения
"OFFERDEPTH" -- Предложение по лучшей цене
"OFFERDEPTHT" -- Суммарное предложение
"NUMOFFERS" -- Количество заявок на продажу
"HIGH" -- Максимальная цена сделки
"LOW" -- Минимальная цена сделки
"LAST" -- Цена последней сделки
"CHANGE" -- Разница цены последней к предыдущей сессии
"QTY" -- Количество бумаг в последней сделке
"VOLTODAY" -- Количество бумаг в обезличенных сделках
"VALTODAY" -- Оборот в деньгах
"VALUE" -- Оборот в деньгах последней сделки
"WAPRICE" -- Средневзвешенная цена
"NUMTRADES" -- Количество сделок за сегодня
"PREVPRICE" -- Цена закрытия
"PREVWAPRICE" -- Предыдущая оценка
"LASTCHANGE" -- % изменения от закрытия
"PRICEMINUSPREVWAPRICE" -- Разница цены последней к предыдущей оценке
"PREVSETTLEPRICE" -- Предыдущая расчетная цена
"PRICEMAX" -- Максимально возможная цена
"PRICEMIN" -- Минимально возможная цена
"NUMCONTRACTS" -- Количество открытых позиций
"BUYDEPO" -- Гарантийное обеспечение продавца
"SELLDEPO" -- Гарантийное обеспечение покупателя
"STEPPRICET" -- Стоимость шага цены
"STEPPRICE" -- Стоимость шага цены (для новых контрактов FORTS и RTS Standard)
"SETTLEPRICE" -- Расчетная цена
"PERCENTRATE" -- Агрегированная ставка
"CLPRICE" -- Котировка последнего клиринга
"REALVMPRICE" -- Текущая рыночная котировка
"STEPPRICECL" -- Стоимость шага цены для клиринга
"STEPPRICEPRCL" -- Стоимость шага цены для промклиринга
"SEC_FACE_VALUE" -- Номинал бумаги
"SEC_SCALE" -- Точность цены |
Так же, в QLua есть функции для получения данных как графиков, так и индикаторов по их уникальным идентификаторам(тэгам), для этого необходимо нужному графику(индикатору) назначить уникальный идентификатор, о том как это делается можете ознакомиться в самом начале "Инструкции по использованию" Индикатора "Мои Сделки". Идентификатор для индикатора добавляется аналогичным способом.
После этого, можно использовать следующие функции для доступа к данным:
-- Функция предназначена для получения КОЛИЧЕСТВА ЛИНИЙ в графике (индикаторе) по выбранному идентификатору
getLinesCount(tag); -- Возвращает число
-- tag - (STRING) идентификатор графика (индикатора), о котором писалось выше
-- Функция предназначена для получения информации о КОЛИЧЕСТВЕ СВЕЧЕЙ по выбранному идентификатору
getNumCandles(tag); -- Возвращает число
-- tag - (STRING) идентификатор графика (индикатора), о котором писалось выше
-- Функция предназначена для получения информации о свечах по идентификатору (заказ данных для построения графика функция не осуществляет, поэтому для успешного доступа нужный график должен быть открыт)
t, n, l = getCandlesByIndex (tag, line, first_candle, count);
-- Параметры:
-- tag – (STRING) строковый идентификатор графика или индикатора
-- line – (NUMBER) номер линии графика или индикатора. Первая линия имеет номер 0
-- first_candle – (NUMBER) индекс первой свечи. !!! ПЕРВАЯ (САМАЯ ЛЕВАЯ) СВЕЧКА ИМЕЕТ ИНДЕКС 0 !!!
-- count – (NUMBER) количество запрашиваемых свечей
-- Возвращаемые значения:
-- t – таблица, содержащая запрашиваемые свечи, пример работы:
local O = t[i].open; -- Получить значение Open для указанной свечи (цена открытия свечи)
local H = t[i].high; -- Получить значение High для указанной свечи (наибольшая цена свечи)
local L = t[i].low; -- Получить значение Low для указанной свечи (наименьшая цена свечи)
local C = t[i].close; -- Получить значение Close для указанной свечи (цена закрытия свечи)
local V = t[i].volume; -- Получить значение Volume для указанной свечи (объем сделок в свече)
local T = t[i].datetime; -- Получить значение datetime для указанной свечи
-- Где i - индекс свечи от 0 до n-1
-- n – количество свечей в таблице t
-- l – легенда (подпись) графика |
Если у Вас появились какие-то вопросы, задайте их в комментариях под статьей !!!
Подскажите, как правильно описать такой же по структуре массив, который возвращает функция getCandlesByIndex? Мне необходимо из считанного getCandlesByIndex сделать другой массив такой же структуры, выполнив определенные преобразования.
Я делаю так, но что-то не получается
Здравствуйте, в вашем примере NewCandles содержит лишь один бар с временной меткой datetime
Добрый день, Господа! Подскажите, как получить через CreateDataSource данные для индикатора с другого таймфрейма. Это будет внутри function OnCalculate(indx) или вне её?
Добрый день. Есть 2 вида скриптов: индикаторы, в которых все расчеты происходят в функции OnCalculate(), которая вызывается терминалом на каждом тике и классические скрипты (роботы), в которых вся работа происходит внутри функции main. Функция CreateDataSource используется в роботах чтобы подключиться к какой-либо бумаге и получать данные о ее свечах. Чтобы получить данные с индикатора другого таймфрейма, Вам нужно либо открыть в терминале график с нужным таймфреймом, установить на него нужный индикатор и получать из него данные при помощи getCandlesByIndex, либо подключиться к нужному Вам таймфрейму при помощи CreateDataSource и программно вычислять значения нужного Вам индикатора.
Добрый день, Дмитрий! Я хотел получить значение индикатора на таймфрейме М5 по свечкам D. Другими словами, вывести значение ATR по дневным свечам в дополнительном окне (например, на М5). Единственная возможность это сделать, по моему мнению - это запросить другой источник данных по нужному таймфрейму, получить свечки, сделать по ним вычисления, а потом вернуть на текущий график. И единственная мне известная функция для этого - CreateDataSource . Только при попытках её использования внутри OnCalculate возникает ошибка. Хотелось в индикаторе получить источник данных, не зависимый от таймфрейма открытого графика. В роботах я знаю, как пользоваться этой функцией. Но вот есть ли возможность её использования в индикаторе? Такая возможность открыла бы массу возможностей для генерации сигналов для робота в части создания дополнительных фильтров по старшим таймфреймам.
Эта функция недоступна внутри индикатора, без робота никак, только в роботе ее использовать и передавать значения в индикатор.
Спасибо, Дмитрий! Значит индикатор работает только с текущим источником. Можно ещё вопрос? Была идея вывести открытый интерес по опционам в виде меток на графике базового актива по дате экспирации из Текущих торгов. Но любое получаемое индикатором значение из указанной таблице приводит к подвисанию терминала (даже, если, например, просто получить теоретическую цену на график цены опциона. Пробовал ограничить по времени сегодняшним днём через условие os.date. Но это к изменениям не привело. Да и вообще, некоторые индикаторы при изменении графика инструмента приводят к зависанию терминала на 15-20 секунд, что во время торговли слишком значительно. И даже такие примитивные индикаторы, как High и Low через период из кол-ва свечей тоже работают медленно на минутных таймфреймах. Подскажите, есть ли какой-нибудь универсальный способ ускорения работы индикаторов?
Скорее всего Вы на каждый тик пытались добавить новую метку на график, или что-то подобное, если тиков много, то терминал зависнет, конечно. Можно и обычными message() терминал повесить, если их много и часто выводить. Тут вопрос оптимизации алгоритма, самое простое, например, запоминать секунду последней проверки и проверять в следующий раз не раньше следующей секунды, или что-то подобное.
Спасибо, Дмитрий! Надо попробовать.
Всегда пожалуйста 🙂
Огромное спасибо за идеи всем отозвавшимся!
Интересные идеи.)))
Обращайтесь )
День добрый!
Нужна информация, содержащаяся в заголовке открытого окна диаграммы (графика) цен по инструменту: код инструмента и тайм-фрейм.
Как можно из скрипта обратиться к данному заголовку, чтобы потом использовать их в скрипте?
Спасибо.
День добрый!
Написать индикатор, который будет транслировать изменения таймфрейма, ну и сам тикер.
А тикер можно получить из легенды
local t, n, l = getCandlesByIndex(tag, 0, getNumCandles(tag)-1, 1)
ticker = string.match(l, "(%w+)")
Спасибо, этот вариант (с использованием get...ByIndex()) я пробовал.
Про string.match() как-то не подумал. Видимо, потому что плохо усвоил форматирующие символы и, как следствие, слаб в операциях со строками.
Но задача несколько иная.
Мне нужен именно заголовок (Capture). Это, вероятно, выглядит слишком оригинально, но мне важно именно такое решение: обращение к окну диаграммы в терминале, получение всех его свойств, но на первых порах мне достаточно только заголовка.
К заголовку окна можно получить доступ используя w32.dll, например.
Но есть сложность, графиков может быть много и по одному инструменту в том числе, т.е. танцы с бубном.
Самый простой и проверенный способ получить интервал графика, это индикатор:
StaticVar.dll нужной версии можно взять тут: https://quik2dde.ru/viewtopic.php?id=61
""" вот эта ёба...ь это кавычки, ска нет слов
if version < 8 then
package.cpath=package.cpath..";"..getWorkingFolder().."/Include/lib/x32/?.dll"
Дима! Почини тебя просят уже несколько лет, у тебя штат программистов
У меня программисты сайты не умеют чинить, но я добрался 🙂
Привет! Отлично!
Ты второй мой коммент прочитал про плаза 2 ?
А не пришел, и в свежих комментариях только этот коммент.
Спрашивают кто может для плаза 2 написать, ты не возьмешься?
Нет, я-ж не умею, хотя после НГ буду ковырять это дело в свободные от отдыха минутки.
Да и моекс на партиции все разбил, старые протоколы претерпят ряд значительных изменений.
Любят у нас свои проблемы, со своей больной жадностью башки, переложить на чужие широкие плечи и умные головы.
Моекс тупо не хочет менять свое железо еще года 3-4, которое они подобрали на помойке, хорошие люди выкинули, а они подобрали.
И, к сожалению у нас так много кто делает, в т.ч. арка.
Понял, удачи в новых познаниях 🙂
Спасибо)
Если нужен заголовок окна, то без dll не обойтись, например можно использовать w32.dll
Не забывайте что Вы можете создать несколько окон с одним и тем же инструментом, тогда Вам придется каждое окно назвать вручную как то уникально, что бы различать эти окна, QUIK позволяет давать заголовки окнам.
В этих окнах располагаются графики и их тоже несколько, цена, объем, индикатор...
- "получение всех его свойств"
- О каких свойствах идет речь? Ну размер окна, его положение еще можно получить, но что еще можно от этого окна получить, непонятно. Или Вы хотите заглянуть в окно? Получили окно, а внутри график цены, заглянули в график цены, а там бары, линии, метки... - Так не получится. Хотя может это и возможно, но как такое реализовать, не представляю.
Достаточно присвоить уникальный идентификатор и не заниматься придумыванием фигни, которая, как в последствии выяснится, не нужна ни мне ни тебе, ни кому.
Если человеку нужно свойство окна, то идентификатор ему не поможет.
Если Вам не нужна, так называемая "фигня", это вовсе не означает, что она не нужна вообще ни кому. Не нам решать, кому что нужно.
Паша, привет!
Программирование это такая штука специфическая.
Можно ушатать много лет на изучение не нужных аспектов, которые никогда не пригодятся в жизни.
Мы и так потратили много времени в саду, школе, институте на Фигню с большой буквы.
У некоторых это вообще вошло в привычку - изучение фигни, а дети тем временем голодные, потому что знание фигни или большого кол-ва фигней, очень редко позволяет заработать на хлеб насущный.
Но, конечно это лишь мое субъективное мнение, а прислушиваться или нет - дело каждого внимающего.
А задача, которую озвучили выше, (получение инструмента и интервала) очень просто решается в 47 строк, без танцев с бубном.
Соглашусь, что получить инструмент и интервал не так сложно и не стоит заморачиваться с поиском окон и прочим.
Но далее было сказано:
"Но задача несколько иная.
Мне нужен именно заголовок (Capture) ..."
Из этого уже следует, что все же придется искать окно, для этого и нужна w32.dll можно конечно и свою dll написать, но суть остается таже. Что дальше автор будет делать с найденным окном уже не известно, да и задача далее не описана. Я не знаю что можно достать из окна, кроме заголовка, положения и размера, может автор сможет достать из него абсолютно все. Так почему же ему говорить сразу, не занимайся фигней, мы ему подсказали что нужно, дальше пусть работает.
Ну если сад, школа, институт - это тоже фигня, тогда я вообще молчу на эту тему.
Я сам очень много потратил времени на написание разных программ, которыми вообще не пользуюсь, 2-3 раза запустил и все, забросил. Но я не считаю что потратил время зря, получил много опыта. Если бы я не писал ничего, то и сейчас бы так ничего бы и не написал.
Если оценивать потраченное время, то получается, что и сад и школа и институт - это зря потраченное время.
И не просто время, а 30% отведенного времени на жизнь.
Система обучения далека от совершенства. Иностранный язык изучают практически на протяжении всего обучения.
При окончании института, реально знают этот язык 2-3% выпускников.
А если приспичит, то этот язык будет выучен за пару месяцев в любом возрасте.
Значит время, потраченное на изучение этого языка прошло зря, как впрочем, и остального.
А путать практику с потребностью, не стоит.
Можно всю жизнь заниматься написанием бесполезных программ и писать их в совершенстве, только толку от них нет и не будет.
А можно один раз заплатить за курс по теме сотку-другую тыс. руб. и потратить пару месяцев на обучение, эффект в разы лучше, чем от самостоятельного изучения литературы, да по разным форумам в течении нескольких лет.
С нулевым входом самостоятельное изучение займет 3-4 года, при условии малой занятости другими делами.
Держите лайфхак:
зарплата дворника около 15тыс.р., считаем:
15 х 12 х 3 = 540 тыс, вуаля.
Вот так, опираясь на знание величины зарплаты дворника, можно посчитать много чего..., например, стоит ли воровать мешок картошки или миллион.
Здравствуйте.
С графиками и индикаторами понятно. Интересует возможность при помощи qlua или сторонних библиотек получить координаты точек линии тренда, построенной вручную. (не индикатора)
Пробовал узнать их используя программу ArtMoney, однако, адреса ячеек памяти, в которые записаны координаты, меняются при перезапуске quik и на них нельзя полагаться. С winApi также не получается, потому что дальше окна графика Chart Window он не может смотреть.
Есть какие-то идеи по поводу возможного решения, хотя бы в каком направлении двигаться?
Здравствуйте, помню что есть библиотека, но не помню как называется, т.к. сам ей не пользовался, надеюсь кто-то подскажет здесь.
А вы не могли бы вспомнить, что она ещё делает, по какому принципу работает? У меня, на самом деле, идей нету, так как не понятен механизм получения данных из закрытого процесса quik.
Дмитрий, а не могли бы Вы как то вспомнить. Очень интересно. Я давно ломаю голову на эту тему.
У меня так же нет вариантов влезть внутрь графика Квика, а хотелось бы, но если речь идет о "линии тренда", то есть немого другая идея.
Получить доступ к линиям построенным вручную нет возможности, но линия тренда не такая сложная, ее можно создать на LUA, а управлять из терминала.
Суть в следующем:
Создать индикатор (именно индикатор, не скрипт).
Для графика цены задать Идентификатор.
Индикатор создает 2 метки в виде картинки, к примеру квадратик 3x3 пикселя, на графике цены используя Идентификатор. Эти метки пользователь может двигать мышью.
Перемещая эти метки пользователь задает 2 точки, а индикатор, основываясь на координатах этих меток, рисует линию. Нужно лишь только опрашивать эти метки, что бы узнать, не изменились ли координаты.
Опрашивать метки можно двумя способами:
При поступлении новой сделки. Когда рынок активный и сделки поступают часто, линия будет реагировать на действия пользователя практически мгновенно, но если сделки поступают раз в несколько секунд, тогда после перемещения метки, линия изменится лишь только когда придет новая сделка.
Другой вариант. Использовать DLL библиотеку, где создать функцию с бесконечным таймером с интервалом например 100мс. Запускаем индикатор, запускается таймер и вызывает функцию с интервалом 100 мс, а внутри этой функции происходит опрос координат меток. В этом случае линия будет реагировать на действия пользователя практически мгновенно независимо от сделок поступающих в терминал.
Это все теоретически, на практике скорее всего нужно будет решить много задач, но думаю идея рабочая.
Что касается остальных фигур, например прямоугольника, то тут уж ни как, линиями индикатора прямоугольник не построить.
Дмитрий,здравствуйте. Функция SetUpdateCallback(MyFuncName) вызывается на каждый тик. Можно ли сделать так (через эту функцию или другую, но не запоминаем параметров свечи) чтобы вызов был именно после формирования ЦЕЛОЙ свечи выбранного таймфрейма?
Здравствуйте, можно отслеживать дату/время текущей свечи, как появился тик новой свечи, значит появилась новая сформированная свеча предыдущая.
Дмитрий, категорически приветствую!
Есть куча не WordPress, у которых отлично построен и РАБОТАЕТ! форум, с редакцией и прочими плюшками и не каверкает символы.
Всякое желание тут чего-то писать пропадает.
Приветствую, Александр! Никак руки не доходят, к сожалению 🙁
после message нужно old_index и(не обозначил) old_index15 приравнять к текущему index. иначе квик захлебнется сообщениями (аркаводы - дебилы не могут отключить процесс, который начинает спамить message)
Привет, Дмитрий.
Подключаю график так -
-- Получает доступ к свечам графика
Отключаюсь так -
При остановке робота - терминал подвисает. Что не так я сделал?
Привет, попробуй DS:Close() убрать из OnStop(), может это не из-за этого вообще подвисает.
Привет, у меня изначально DS:Close() в OnStop() не было - все равно подвисал.
Ну значит причина подвисания не в DS вообще 🙂
И как то через раз то виснет то нет, код обычный ни чего нового не прикручивал
Подозреваю, что это KillAll()
Здесь виснуть нечему
Да, тогда не знаю
Добрый день, Дмитрий!
Каким образом можно получить с открытого графика данные фьючерса SiM9 (ГГГГMMДД, ЧЧММСС, OPEN, LOW, HIGH, CLOSE) для дальнейшего сохранения в файл (это уже умею)?
И еще, как можно проверить отсутствие части котировок в файле, чтобы затем получить недостающие свечи? Все на форуме прочитано, вижу, истина где-то рядом, но как всегда знаний не хватает 🙂
Заранее благодарен!
Здравствуйте, в данной статье приведены 2 примера с комментариями, не знаю что еще можно подсказать, просто берите примеры и пробуйте.
Доброго времени суток! Могли бы мне помочь. У меня такая ситуация. Я не могу понять как обратиться к каждой линии в индикаторе price Channel когда создаю сигнал на покупку или продажу
if ind~=nil and ind~="" then
local N=getNumCandles(ind);
if N 10 then
-- upper
t,n,i=getCandlesByIndex(ind, 0, N-2, 2);
prevCloseUpper = math.floor(tonumber(t[0].close) * precision) / precision; -- предыдущее закрытие верхней линии индикатора PriceChannel
closeUpper = math.floor(tonumber(t[1].close) * precision) / precision; -- закрытие верхней линии индикатора PriceChannel
-- lower
t,n,i=getCandlesByIndex(ind, 2, N-2, 2);
prevCloseLower = math.floor(tonumber(t[0].close) * precision) / precision; -- предыдущее закрытие нижней линии индикатора PriceChannel
closeLower = math.floor(tonumber(t[1].close) * precision) / precision; -- закрытие нижней линии индикатора PriceChannel
ДАЛЕЕ ХОЧУ СРАВНИТЬ
if PRICE<0 then
SIGNAL="BAY"
if PRICE==2 then
SIGNAL="SELL"
Здравствуйте, на сколько можно понять из этого кода (в следующий раз оборачивайте его в теги луа, над полем ввода комментария написано) подход, вроде бы, верный. Но если что-то работает не так, как ожидается, то для этого можно при помощи message выводить значения переменных и тогда станет ясно где ошибка.
-- upper
t,n,i=getCandlesByIndex(ind, 0, N-2, 2); -->, 0, = свечной график, попробуйте 1
Здравствуйте, я вот не понял, а как получить значение индикаторов то на свече? Вызываю функцию getCandlesByIndex с идентификатором индикатора получаю таблицу, где все параметры (open ... volume), кроме datetime нулевые...
Здравствуйте, значит как-то не так вызываете 🙂