Алена, ошибка найдена и исправлена. Архив на сайте обновим завтра. Пока можно взять исправленный код индикатора ниже
Скрытый текст
Код
Settings = {
Name = "*BWMFI (Bill Williams Market Facilitation Index)",
line = {{
Name = "Horizontal line",
Type = TYPE_LINE,
Color = RGB(140, 140, 140)
},
{
Width = 3,
Name = "BWMFI_Green",
Type = TYPE_HISTOGRAM,
Color = RGB(0, 206, 0)
},
{
Width = 3,
Name = "BWMFI_Fade",
Type = TYPE_HISTOGRAM,
Color = RGB(128, 64, 0)
},
{
Width = 3,
Name = "BWMFI_Fake",
Type = TYPE_HISTOGRAM,
Color = RGB(0, 255, 255)
},
{
Width = 3,
Name = "BWMFI_Squat",
Type = TYPE_HISTOGRAM,
Color = RGB(255, 0, 255)
}
},
Round = "off",
Multiply = 1,
Horizontal_line="0"
}
function Init()
func = BWMFI()
return #Settings.line
end
function OnCalculate(Index)
local Out = ConvertValue(Settings, func(Index, Settings))
local HL = tonumber(Settings.Horizontal_line)
if Out then
local prev = GetValue(Index-1, 2) or GetValue(Index-1, 3) or GetValue(Index-1, 4) or GetValue(Index-1, 5) or 0
local prev_v = V(Index-1) or 0
if (Out > prev) and (V(Index) > prev_v) then
return HL,Out,nil,nil,nil
elseif (Out <= prev) and (V(Index) <= prev_v) then
return HL,nil,Out,nil,nil
elseif (Out > prev) and (V(Index) <= prev_v) then
return HL,nil,nil,Out,nil
elseif (Out <= prev) and (V(Index) > prev_v) then
return HL,nil,nil,nil,Out
else
return HL,nil,nil,nil,nil
end
else
return HL,nil,nil,nil,nil
end
end
function BWMFI() --Bill Williams Market Facilitation I ("BWMFI")
local it = {p=0, l=0}
return function (I, Fsettings, ds)
if I == 1 then
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then it={p=I, l=it.l+1} end
return GetValueEX(it.p, DIFFERENCE, ds) / GetValueEX(it.p, VOLUME, ds)
end
return nil
end
end
SMA,MMA,EMA,WMA,SMMA,VMA = "SMA","MMA","EMA","WMA","SMMA","VMA"
OPEN,HIGH,LOW,CLOSE,VOLUME,MEDIAN,TYPICAL,WEIGHTED,DIFFERENCE,ANY = "O","H","L","C","V","M","T","W","D","A"
function CandleExist(I,ds)
return (type(C)=="function" and C(I)~=nil) or
(type(ds)=="table" and (ds[I]~=nil or (type(ds.Size)=="function" and (I>0) and (I<=ds:Size()))))
end
function Squeeze(I,P)
return math.fmod(I-1,P+1)
end
function ConvertValue(T,...)
local function r(V, R)
if R and string.upper(R)== "ON" then R=0 end
if V and tonumber(R) then
if V >= 0 then return math.floor(V * 10^R + 0.5) / 10^R
else return math.ceil(V * 10^R - 0.5) / 10^R end
else return V end
end
if arg.n > 0 then
for i = 1, arg.n do
arg[i]=arg[i] and r(arg[i] * ((T and T.Multiply) or 1), (T and T.Round) or "off")
end
return unpack(arg)
else return nil end
end
function GetValueEX(I,VT,ds)
VT=(VT and string.upper(string.sub(VT,1,1))) or ANY
if VT == OPEN then --Open
return (O and O(I)) or (ds and ds:O(I))
elseif VT == HIGH then --High
return (H and H(I)) or (ds and ds:H(I))
elseif VT == LOW then --Low
return (L and L(I)) or (ds and ds:L(I))
elseif VT == CLOSE then --Close
return (C and C(I)) or (ds and ds:C(I))
elseif VT == VOLUME then --Volume
return (V and V(I)) or (ds and ds:V(I))
elseif VT == MEDIAN then --Median
return ((GetValueEX(I,HIGH,ds) + GetValueEX(I,LOW,ds)) / 2)
elseif VT == TYPICAL then --Typical
return ((GetValueEX(I,MEDIAN,ds) * 2 + GetValueEX(I,CLOSE,ds))/3)
elseif VT == WEIGHTED then --Weighted
return ((GetValueEX(I,TYPICAL,ds) * 3 + GetValueEX(I,OPEN,ds))/4)
elseif VT == DIFFERENCE then --Difference
return (GetValueEX(I,HIGH,ds) - GetValueEX(I,LOW,ds))
else --Any
return (ds and ds[I])
end
return nil
end
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Вычитание из числа округленного до сотых числа округленного до сотых, В скрипте две переменных, округленные до сотых. Из одной вычитается другая. Результаты математической операции ниже:
Сергей написал: В мануале не написано как правильно сделать.
параметры транзакций описаны в руководстве: -Раздел 6. Совместная работа с другими приложениями --Импорт транзакций ---Формат .tri-файла с параметрами транзакций
Сергей написал: Как выставить роботом - до отмены?
EXPIRY_DATE = GTC
Цитата
Сергей написал: Как правильно писать дату если указывать до даты?
EXPIRY_DATE = Дата в формате «ГГГГММДД»
Цитата
Сергей написал: pOFFSET_UNITS="%" и pOFFSET_UNITS="Д" ??? pSPREAD_UNITS="%" и pSPREAD_UNITS="Д" ???
в руководстве нет таких значений "%" и "Д" есть такие: «PERCENTS» – в процентах (шаг изменения – одна сотая процента), «PRICE_UNITS» – в параметрах цены (шаг изменения равен шагу цены по данному инструменту).
Цитата
Сергей написал: Как правильно указать значение, в кавычках, как строку?
Да в кавычках как строку.
Цитата
Сергей написал: ПРАВИЛЬНО ЛИ Я СФОРМИРОВАЛ ЗАЯВКУ????
Примеры параметров транзакций есть в руководстве -Раздел 6. Совместная работа с другими приложениями --Импорт транзакций ---Формат .tri-файла с параметрами транзакций ----Примеры строк, которые могут содержаться в файле
Михаил Ершов написал: Луа так понимаю локальный язык, с брокером никак не связан.
Lua отправляет транзакции в терминал Терминал, отправляет их на сервер брокера. Сервер брокера отправляет их на биржу, где и происходит торговля. И именно биржа, а не Lua и не сервер брокера шлет ответ о регистрации заявки. К слову Trans2Quik работает точно также. Другое дело если заявка не зарегистрирована, а была отвергнута, но Вы же говорите что заявка зарегистрировалась. Если ответа на транзакцию не было, значит на каком-то участке случилась проблема и ответ не пришел. На терминале в таблице транзакций, был ответ? Если да то только тогда можно думать что есть проблема в Lua иначе она где-то в другом месте (на участке от сервера до биржи). По логам брокера можем проверить что было на участке от сервера до биржи, был ли ответ или нет. И если был тогда разбираться с терминалом или с lua.
Цитата
Михаил Ершов написал: В личные сообщения могу прислать...
Михаил Ершов, Михаил, в общем если хотите использовать lua + Trans2Quik то мы в такой связке их не тестировали и что будет не понятно. Потому что в Lua есть всё что есть в Trans2Quik, а значит такая связка на наш взгляд вообще не требуется. Если есть проблема с Lua мы готовы разбираться, но нам нужен конкретный пример. Пока же просто проверьте актуальные ли у Вас версии (терминал QUIK 7.19 и qlua.dll версии 2.7.0.3)
Михаил Ершов написал: в паре с Lua скриптом использовать trans2quik
Зачем? Всё что есть в trans2quik уже есть в Lua
Цитата
Михаил Ершов написал: Сталкиваюсь с проблемой иногда что в Lua не приходят транзакции с номером заявки,
Если есть проблема следует разобраться с причиной проблемы, а потом уже делать выводы. Приведите пример такой такой транзакции (скриншот или лог), сообщите Ваш UID и кто брокер.
Цитата
Михаил Ершов написал: Посоветовали trans2quik как "прямой API" к квику,
trans2quik работает с терминалом QUIK и Lua тоже самое, работает с терминалом QUIK.
Егор Масалкин написал: Вопрос. Есть ли какие-то особенности при вызове этой функции на реальном счете?
нет никаких особенностей
Цитата
Егор Масалкин написал: Скрипт выдаёт ошибку, мол, attempt to index a nil value
проверьте корректно ли заданы параметры Firm_ID, Account и currcode. Значение всех параметров функции можно посмотреть в таблице "Ограничения по клиентским счетам": Firm_ID - Фирма, Account - Торговый счет, currcode - Валюта позиции. Скорей всего проблема именно в currcode
Здравствуйте, В INCLUDE файле не нужны какие-либо заголовки, просто описываете функции и всё. расширение файла не имеет значения, главное чтобы это был текстовый файл. Далее в основном QPILE скрипте пишите строку INCLUDE на добавление файла После этого в основном файле можно использовать функции из INCLUDE файла
bstone написал: С DDE ситуация еще более-менее понятна, но почему при копировании содержимого пользовательской таблицы в буфер обмена по CTRL+C, туда попадает не ее содержимое, а нули?
Проблема изучается. Постараемся в ближайшее время дать ответ.
Andrei2016 написал: В этой связи еще один вопрос: чем различаются типы QTABLE_CACHED_STRING_TYPE и QTABLE_STRING_TYPE? В документации о различиях - ни слова. На что влияет замена одного типа другим, в каких случаях?
При использовании QTABLE_CACHED_STRING_TYPE в ячейке таблицы хранится ссылка на специальную таблицу уникальных строковых констант, которая заполняется по мере добавления данных. Это экономит память при многократном использовании повторяющихся значений. Например, если Вы хотите создать аналог таблицы всех сделок, то поле "направление сделки" может принимать значение "Покупка" или "Продажа". В этом случае использование QTABLE_CACHED_STRING_TYPE для столбца будет наиболее эффективным.
Цитата
Andrei2016 написал: Прошу прокомментировать с уточнением порядка функционирования OnParam().
Раз в таймаут происходит запрос данных с сервера и далее срабатывает OnParam. Если свежих данных на сервере нет, то старые повторно не запрашиваются. как только появятся новые данные, запрос их вернет и сработает OnParam. Следует отметить что список данных которые запрашиваются, формируется либо автоматически (если включена опция "Исходя из настроек открытых пользователем таблиц") либо вручную, через меню Система - "Заказ данных" - "Поток котировок". Можно легко проверить на каком-нибудь инструменте который редко обновляется, например из класса кросс курсов.
Andrei2016 написал: 1) отображение измененной в OnParam() ячейки (1, 1) может произойти почти сразу, но отображение изменения ячейки (9, 1) только после изменения котировки инструмента;
Эта ситуация у нас воспроизвелась только один раз, при срабатывании OnParam() в момент формирования таблицы в main(). Для исключения такой ситуации рекомендуем добавить флаг включающий работу OnParam только после окончания формирования таблицы (т.е. перед циклом while). пример:
Код
doParam = false
--прочий код
function OnParam()
if doParam then
--остальной код
end
end
--прочий код
function main()
--тут формируем таблицу
doParam = true
while (not isStopped) do
--работа цикла
end
--остальной код
end
Цитата
Andrei2016 написал: 2) лучше всего это видно на вечерней сессии после 19-00, даже после 19-30, когда скорость изменения котировок падает очень сильно, и паузы превышают установленные для OnParam() 5 секунд - они могут быть и 20 - 40 секунд;
Если новых данных нет, то OnParam не сработает. Скорей всего Вы столкнулись именно с этим.
Цитата
Andrei2016 написал: если я при добавлении столбца указываю тип QTABLE_STRING_TYPE - столбец не добавляется, как ни крути. Возвращаюсь обратно к QTABLE_CACHED_STRING_TYPE - столбец появляется.
Ситуация не воспроизводится. Колонки с типом QTABLE_STRING_TYPE прекрасно добавляются. Возможно у Вас при добавлении возникает какая-то ошибка? Если да то какая? Проверьте на всякий случай, все ли параметры указаны верно.
Цитата
Andrei2016 написал: периодически (особенно в период медленного обновления таблицы текущих торгов после 19-00) происходит отбраковка функции SetCell: функция вовзращает false при стандартном занесении строки в столбец с типом STRING.
на наш взгляд это тоже что и п.1. т.е. срабатывание OnParam() в момент формирования таблицы в main(). При других обстоятельствах у нас ситуация не воспроизвелась.
Разница в том что на сайте биржи начало свечки совпадает с началом вечерней сессии, а в QUIK свечки формируются после полуночи.
Цитата
aidan1387 написал: Хотелось бы узнать, есть ли возможность добиться совпадения хоть каким-нибудь способом на клиентской стороне (настройки, скрипты и тд)?
Suntor, Здравствуйте, Описанная ситуация у нас не воспроизводится. Пришлите на quiksupport@arqatech.com для анализа полный исходный код lua скрипта, на котором проблема повторяется и *.dmp файл пусть к которому указан у Вас на скриншоте.
Здравствуйте, К сожалению мы не будем добавлять поддержку python скриптов, по нашим внутренним причинам. То же касается и любых других видов скриптов. В QUIK поддерживается QLUA к котрому можно подключать сторонние библиотеки написанные на произвольном языке. И есть Trans2quik.dll который позволяет реализовать свою программу для отправки транзакций в терминал
Andrei2016 написал: далеко не всегда обновление пользовательской таблицы/окна происходит сразу же после изменения содержимого одной или нескольких ячеек
Цитата
Andrei2016 написал: периодически (особенно в период медленного обновления таблицы текущих торгов после 19-00) происходит отбраковка функции SetCell: функция вовзращает false при стандартном занесении строки в столбец с типом STRING.
Приведите пример кода на котором воспроизводятся проблемы и сообщите версию терминала QUIK
Александр, Если у Вас та же ошибка про time_in_force то это вопрос к бирже. Рекомендуем обратиться к своему брокеру по данному вопросу, чтобы он выяснил причины у специалистов биржи.
Andrey, Код фирмы (firm_id) видно в таблице Клиентский портфель, в колонке "Фирма" Код клиента (client_code) видно в таблице Клиентский портфель, в колонке "Код клиента"
Здравствуйте, Проверьте корректно ли задан первичный ключ в базе данных. Для таблицы текущих торгов, первичный ключ должен содержать параметр "Инструмент"
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Let_it_go написал: Почему? Второй подписался на тики, и они передаются на первый?
Подписка не привязана к конкретному скрипту. Один скрипт заказал данные, они пришли в терминал. Значит другой сможет с ними работать, потому что в терминале данные уже есть. И не важно как данные в терминале появились, через открытие таблицы, через тиковый график или их заказал Lua скрипт. Иными словами, в QLUA функции работают с данными в терминале, а не с таблицами. А открытие таблицы это лишь один из способов заказать данные. В понимании этого и кроется ответ на вопрос.
Можно в терминале QUIK открыть 1000 одинаковых таблиц, но поток данных будет один на все таблицы, и Lua будет работать с этим потоком, а не с 1000 таблицами. Это хорошо видно если открыть несколько таблиц обезличенных сделок, и в каждой настроить свой фильтр по инструменту. В Lua Вы получите один сплошной поток по всем выбранным инструментам. Как следствие, можно в одном LUA скрипте заказать данные, но поток данных будет все равно один и он будет доступен во всех Lua скриптах.
Let_it_go написал: Мне нужно его прочитать с помощью
не возможно без этого
Цитата
Sergey Gorokhov написал: "как передать файл с одного компа на другой"
Чтение по сети, это тоже своего рода "перекидывание" файла, только через сетевую папку. Если нет доступа к файлу, не сможете выполнить dofile и код тут сейчас совершенно не причем. Когда получите доступ к файлу, далее будем думать как выполнить dofile
Если получится через папку, то делайте через папку
Цитата
Let_it_go написал: Папку с файлом на первой виртуалке нужно сделать общей.
Если нет, варианты были озвучены.
Если доступ через папку уже есть и работает (попробовать открыть файл в проводнике) тогда просто укажите в dofile сетевой путь как то так:
Let_it_go написал: Господа, вопрос не совсем по Луа.
Вы правильно заметили что вопрос не связан с Lua. Ваш вопрос в принципе не связан с QUIK.
Ваш вопрос звучит так "как передать файл с одного компа на другой" и на этот вопрос в интернете можно найти целый список ответов (честно не читал что там, но суть понятна). Если по локальной сети через сетевую папку, не получается, попробуйте другие варианты через интернет.
Когда Вы найдете способ, тогда уже можно вернуться к Lua