Разработчики сделали доброе дело - написали функцию фракталов. Но как её вызывать не понятно. Я пробую это делать так (для списка бумаг), но безрезультатно. Судя по коду индикатора, он выдаёт на выходе 2 переменные - ближайший верхний и ближайший нижний фрактал. Колбек ДатаСорс работает, но f_1 и f_2 не получают никаких значений.
Код
function mycallbackforallstocks(class,sec,index)
local num_candles=ds[sec]:Size()
if index==num_candles then
last_price[sec]=ds[sec]:C(num_candles)
message (sec.." here "..last_price[sec])
tbl:SetValue(line_count_table[sec],'last', last_price[sec])
tbl:Highlight(line_count_table[sec],'SEC',WHITE,RED,1000)
func =FRACTALS()
for i=1,ds[sec]:Size() do
f_1,f_2=func(i, {Period=30}, ds[sec])
message (sec.." "..f_1.." "..f_2)
end
end
end
function DataSource(class,sec,interval)
ds[sec] = CreateDataSource(class,sec,interval)
ds[sec]:SetUpdateCallback(function(...) mycallbackforallstocks(class,sec,...) end)
return ds[sec]
end
Вот сам код индикатора. Прошу помочь. Второй вопрос. Как с его помощью вызывать не только ближайшие фракталы, но и многие другие фракталы - поза-предыдущий, поза-поза-предыдущий? Спасибо.
Код
Settings = {
Name = "*FRACTALS (Fractals)",
Period = 5,
line = {{
Name = "FRACTALS - Down",
Type = TYPE_TRIANGLE_DOWN,
Color = RGB(255, 0, 0)
},
{
Name = "FRACTALS - Up",
Type = TYPE_TRIANGLE_UP,
Color = RGB(0, 255, 0)
}
}
}
function Init()
func = FRACTALS()
return #Settings.line
end
function OnCalculate(Index)
return func(Index, Settings)
end
function FRACTALS() --Fractals ("FRACTALS")
local H_tmp={}
local L_tmp={}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 5)
P = math.floor(P/2)*2+1
H_tmp[I]=Value(I,"High",ds)
L_tmp[I]=Value(I,"Low",ds)
if I>=P then
local S = I-P+1+math.floor(P/2)
local val_h=math.max(unpack(H_tmp,I-P+1,I))
local val_l=math.min(unpack(L_tmp,I-P+1,I))
local L = Value(S,"Low",ds)
local H = Value(S,"High",ds)
if (val_h == H) and (val_h >0)
and (val_l == L) and (val_l > 0) then
if ds then return S,S else
SetValue(S, 1, val_l)
SetValue(S, 2, val_h)
end
else
if (val_h == H) and (val_h >0) then
if ds then return S,nil else
SetValue(S, 1, nil)
SetValue(S, 2, val_h)
end
end
if (val_l == L) and (val_l > 0) then
if ds then return nil,S else
SetValue(S, 1, val_l)
SetValue(S, 2, nil)
end
end
end
end
return nil,nil
end
end
function Value(I,VType,ds)
local Out = nil
VType=(VType and string.upper(string.sub(VType,1,1))) or "A"
if VType == "O" then --Open
Out = (O and O(I)) or (ds and ds:O(I))
elseif VType == "H" then --High
Out = (H and H(I)) or (ds and ds:H(I))
elseif VType == "L" then --Low
Out = (L and L(I)) or (ds and ds:L(I))
elseif VType == "C" then --Close
Out = (C and C(I)) or (ds and ds:C(I))
elseif VType == "V" then --Volume
Out = (V and V(I)) or (ds and ds:V(I))
elseif VType == "M" then --Median
Out = ((Value(I,"H",ds) + Value(I,"L",ds)) / 2)
elseif VType == "T" then --Typical
Out = ((Value(I,"M",ds) * 2 + Value(I,"C",ds))/3)
elseif VType == "W" then --Weighted
Out = ((Value(I,"T",ds) * 3 + Value(I,"O",ds))/4)
elseif VType == "D" then --Difference
Out = (Value(I,"H",ds) - Value(I,"L",ds))
elseif VType == "A" then --Any
if ds then Out = ds[I] end
end
return Out
end
Здравствуйте, У фракталов есть свои особенности, в указанной функции используется SetValue, которая работает только с графиком, а не источником данных DataSource.
Сергей, ответ не понятен Мне нужно положить этот индикатор в папку LuaIndicators? Или надо на график накладывать фракталы и присваивать идентификатор? А потом как обратиться к значениям фракталов? Передайте привет человеку, который писал этот прекрасный код, но ключики от него спрятал на дне океана.
Что именно не понятно? Почитайте в документации про функцию SetValue.
Цитата
Космонавт написал: А потом как обратиться к значениям фракталов?
Уже было сказано что через DataSource использовать FRACTALS() не получится, только через окно графика стандартным образом, как через любой другой индикатор. т.е. функцией getCandlesByIndex
Цитата
Космонавт написал: Передайте привет человеку, который писал этот прекрасный код, но ключики от него спрятал на дне океана.
Вы не поверите, но эти примеры писал лично я, по своей личной инициативе.
Sergey Gorokhov написал: Вы не поверите, но эти примеры писал лично я, по своей личной инициативе.
я сразу заподозрил, что этот код - ваших рук дело. Вы в него добавили побольше упоминаний ds, чтобы все думали, что можно использовать ДатаСорс. Но не тут-то было ;)))))
Космонавт написал: При чём здесь SetValue? Она нужна, чтобы установить значение на линии индикатора. А мне нужно не установить, а считать значение фрактала!
Вот именно, что она меняет их на графике а Вам надо НЕ на графике а в ds т.е. в этом месте нужно дописать возврат данных.
Не понятно. Покажите пожалуйста на примере. Доведите доброе дело до конца, раз уж начали. Заранее спасибо. Мне действительно очень нужен ваш индикатор. И как считывать не только последние но и другие предыдущие фракталы
Космонавт написал: Не понятно. Покажите пожалуйста на примере.
Что именно не понятно. Конкретику пожалуйста.
Мне нужно переменной Fractal_Up задать значение последнего верхнего фрактала, а переменной Fractal_Up_prev значение предыдущего верхнего фрактала. Как это сделать с помощью Вашей функции?
Добавляете график, добавляете индикатор, в индикаторе заполняете Идентификатор и далее функцией getCandlesByIndex ищите нужный фрактал. описание функции приведено в документации QLUA.chm -Функции взаимодействия скрипта Lua и Рабочего места QUIK --Функции для работы с графиками ---getCandlesByIndex
Я уже давно пользуюсь функцией, которая ищет фрактал через GetCandlesByIndex. Не понятно в чём прорыв при использовании вашей функции, если я и так могу это делать.
Код
function SearchFractals()
local bars_count=getNumCandles(fractal_name)
--toLog(log,"SearchFractals started. Bars_count="..bars_count)
for i=bars_count-4,0,-1 do
local candle,_,_=getCandlesByIndex(fractal_name,0,i,1)
if upFractal==0 and candle[0].high~=0 then
upFractal=candle[0].high
upFractalBar=i
--toLog(log,"SearchFractals upFractal="..upFractal.." upFractalBar="..upFractalBar)
end
if downFractal==0 and candle[0].low~=0 then
downFractal=candle[0].low
downFractalBar=i
--toLog(log,"SearchFractals downFractal="..downFractal.." downFractalBar="..downFractalBar)
end
if downFractal~=0 and upFractal~=0 then
--toLog(log,"SearchFractals all fractals found")
return
end
end
end
Сергей, не обижайтесь, но когда на мои идиотские вопросы дают ответ Камынин, сверг или Майк, мне сразу всё понятно и я остаюсь доволен. А они не сотрудники Арки!!! А с вами постоянно проблемы.
Космонавт написал: Я уже давно пользуюсь функцией, которая ищет фрактал через GetCandlesByIndex. Не понятно в чём прорыв при использовании вашей функции, если я и так могу это делать.
Код
function SearchFractals ()
local bars_count = getNumCandles (fractal_name)
- - toLog(log,"SearchFractals started. Bars_count = "..bars_count)
for i=bars_count-4,0,-1 do
local candle,_,_=getCandlesByIndex(fractal_name,0,i,1)
if upFractal==0 and candle[0].high~=0 then
upFractal=candle[0].high
upFractalBar=i
--toLog(log," SearchFractals upFractal = "..upFractal.." upFractalBar = "..upFractalBar)
end
if downFractal==0 and candle[0].low~=0 then
downFractal=candle[0].low
downFractalBar=i
--toLog(log," SearchFractals downFractal = "..downFractal.." downFractalBar = "..downFractalBar)
end
if downFractal~=0 and upFractal~=0 then
--toLog(log," SearchFractals all fractals found")
return
end
end
end
Разве этот код находит фракталы? Судя по нему, он просто присваивает хаи и лои локальным переменным с шагом назад. Это не имеет отношения к локальным пикам-фракталам.
Подскажите пожалуйста. Пытаюсь вывести значение фрактала, однако все равно получаю ноль.
local k=getNumCandles(chart3) m=getCandlesByIndex(chart3, 0, k-2, 1) message("Значение фрактала "..m[0].close)
Все время значение - ноль.
Цитата
Sergey Gorokhov написал: Добавляете график, добавляете индикатор, в индикаторе заполняете Идентификатор и далее функцией getCandlesByIndex ищите нужный фрактал. описание функции приведено в документации QLUA.chm -Функции взаимодействия скрипта Lua и Рабочего места QUIK --Функции для работы с графиками ---getCandlesByIndex
Все из этого вроде сделано. Если в этот код вставить график МА, то значения выходят.Что не так я сделал?
Объясняю про фрактал. Эта функция написана плохо по следующей причине, так как она заглядывает в будущее. В ней как можно заметить используется поиск максимума и минимума на некотором интервале истории. т е функция работает назад. А значения на график выставляет задним числом тоже назад. ------------------------------- Т е например на графике 10 свечек. фрактал нарисован над 5- той. Но когда было 6 свечей фрактала над 5-ой не было и когда 7 и когда 8 и вот когда стало 9 фрактал появился над пятой свечой. ----------------------------------- Т е функция найдет этот максимум после того как на графике нарисуются , например, 8 свечей и поставит фрактал на 5 свечу, когда нарисует уже 9-ю. ----------------------------- Поэтому такие индикаторы называются - индикаторы заглядывающие в будущие. Обычно на таких индикаторах очень хорошо работают торговые роботы на истории и потом плохо работают такие роботы в реале. Поэтому и фрактал надо искать назад в прошлое.
В качестве пример привожу картинку правильного индикатора, который не заглядывает в будущее и строит все возможные уровни сопротивления и поддержки для имеющейся истории.
Спасибо за ответ. Попытаюсь объяснить по другому. Мне нужно вывести 4 значения максимумов или минимумов свечей последних фракталов. На настоящем этапе я не могу получить значение даже одного. Каким образом это можно сделать? Что за индикатор дает такую картину?
Pavel написал: Спасибо за ответ. Попытаюсь объяснить по другому. Мне нужно вывести 4 значения максимумов или минимумов свечей последних фракталов. На настоящем этапе я не могу получить значение даже одного. Каким образом это можно сделать? Что за индикатор дает такую картину?
Есть два варианта. 1) Читаете график с экрана и ищите не нулевое значение (не помню точно в каком из параметров ) это значение будет всегда на несколько свечей назад. Так двигаясь справа налево ищите ненулевые значения сколько надо . ----------------------------------------------- 2) Строите сами экстремумы функции цены ( это и есть "фракталы", но это название математически безграмотное , поэтому правильно их называть экстремумами ) Как определить экстремум можно найти в любом справочнике по математике или в интернете. Эти экстремумы строите слева направо и пишите их в массив. В результате получите все экстремумы (я их называю экстремумы первого уровня). Ну и так далее...
Спасибо. Первый вариант не подойдет по причине движения графика и когда образуется фрактал заранее не узнать. Попробую через массив... Хотя вроде эти же фракталы определены стандартным индикатором и наверное можно вытащить значения цены на этих свечах.
Pavel написал: Спасибо. Первый вариант не подойдет по причине движения графика и когда образуется фрактал заранее не узнать. Попробую через массив... Хотя вроде эти же фракталы определены стандартным индикатором и наверное можно вытащить значения цены на этих свечах.
Вам не надо знать когда образуется фрактал, Вам надо его найти Вы ищите от последнего найденного до текущей свечи. Начинаете с 1 и ищите до текущей свечи. Когда найдете, то запомните номер свечи в таблице и начнете с этого номера В результате получите таблицу, в которой будут номера свечей фракталов слева на права. Последний всегда будет последним в таблице потом слева предпоследний и так все существующие. Т е то, что Вы хотите.
Начинаете с 1 и ищите до текущей свечи. Когда найдете, то запомните номер свечи в таблице и начнете с этого номера В результате получите таблицу, в которой будут номера свечей фракталов слева направо. Последний фрактал всегда будет последним в таблице. Т е то, что Вы хотите.
Pavel написал: Спасибо. Первый вариант не подойдет по причине движения графика и когда образуется фрактал заранее не узнать. Попробую через массив... Хотя вроде эти же фракталы определены стандартным индикатором и наверное можно вытащить значения цены на этих свечах.
Вот сделал функцию которая выбирает все фракталы https://yadi.sk/d/0eUVB7mC3HFpmH скапируйте этот файл в каталог индикаторов "LuaIndicators" который в каталоге QUIK Вот пример индикатора в котором используется эта функция В окне сообщений покажет все номера выбранных фракталов
Код
--title="<Nikolay Kamynin> kamnik@mail.ru"
Settings={
f1 ="fractals", -- это идентификатор индикатора фрактал его надо записать в дополнительные параметры индикатора
Name = "*nk_fr_get", --имя этого индикатора
mline=0, --номер линии с графиком фрактал
}
-- выбираем фракталы в результате будет создана таблица tf
-- tf - таблица номеров свечей с фракталами
path = "./LuaIndicators/"
package.path =package.path..";"..path.."?.luac;"
require "nk_get_fr";
----------------
function Init()
Settings.line={}; Settings.line[1]={Name = "A",Color = RGB(0,255,0),Type =1,Width = 2 };
return #Settings.line;
end
---------------
function OnCalculate(i)
nk_get_fr.get_fractals(i);
if i==Size() then
local m=1; while #tf>m do message(tostring(tf[m]),1); m=m+1; end
end
end
Николай Камынин написал: Вам не надо знать когда образуется фрактал, Вам надо его найти Вы ищите от последнего найденного до текущей свечи. Начинаете с 1 и ищите до текущей свечи. Когда найдете, то запомните номер свечи в таблице и начнете с этого номера В результате получите таблицу, в которой будут номера свечей фракталов слева на права. Последний всегда будет последним в таблице потом слева предпоследний и так все существующие. Т е то, что Вы хотите.
Стандартный индикатор фракталов ведь показывает образованные фракталы. Зачем писать еще один индикатор и почему из стандартного нет возможности вынуть значения цен на фрактальных свечах? Большое спасибо за функцию!
Николай Камынин, сколько не пытался разобраться с индикатором, так и не смог его толком запустить. У меня в итоге выходит сообщение со счетчиком (я так понимаю это номера фракталов) , которое потом обновляется и приводит к зависанию QUIK.
Здравствуйте Sergey Gorokhov. Разрешите задать Вам, как разработчику этого индикатора, несколько вопросов по его коду:
1. Поясните пож-та использование ds. 2. Зачем в функции return function (I, Fsettings, ds) Вы используете ds, если обращаетесь к этой функции без ds (return func(Index, Settings))? 3. Зачем в теле этой функции проверка условий (val_h > 0) и (val_l > 0)? 4. Поясните конструкцию Out = (O and O(I)) or (ds and ds:O(I)). 5. О каком заглядывании в будущее говорил выше г-н Камынин? 6. Наверное, в индикатор нужно добавить проверку на отсутствующие бары, которые могут возникнуть при остановках сервера, ведь в этом случае фракталы могут неправильно сформироваться.
Mikhail Ran написал: 1. Поясните пож-та использование ds.
цитата из readme_LuaIndicators.txt:
Цитата
data_source - является не обязательным, указывает на таблицу, или источник DataSource
т.е. индикаторы совсем не обязательно использовать только в окне с графиком, можно и через функцию CreateDataSource, для этого и нужен параметр ds.
Цитата
Mikhail Ran написал: 3. Зачем в теле этой функции проверка условий (val_h > 0) и (val_l > 0)?
Причины уже не вспомнить, видимо была какая-то защита от некорректных данных. Эти индикаторы предоставляются "как есть" т.е. если Вам что-то не нравится в коде, смело меняйте так как Вам этого хочется.
Цитата
Mikhail Ran написал: 4. Поясните конструкцию Out = (O and O(I)) or (ds and ds:O(I)).
оно возвращает O(I) или ds:O(I) в зависимости от того что существует. если индикатор добавлен на график, то вернет O(I), если индикатор используется из DataSourceто вернет ds:O(I)
Цитата
Mikhail Ran написал: 5. О каком заглядывании в будущее говорил выше г-н Камынин?
Так и задайте этот вопрос г-ну Камынину.
Цитата
Mikhail Ran написал: 6. Наверное, в индикатор нужно добавить проверку на отсутствующие бары, которые могут возникнуть при остановках сервера, ведь в этом случае фракталы могут неправильно сформироваться.
Подскажите, как получить данные по последним (верхним и нижним) фракталам. График с индикатором открыт, идентификатор присвоен. Данные свечей и других индикаторов получаю через getNumCandles. С фракталами не могу разобраться никак. Прошу сильно не пинать, начинающий я))
Здравствуйте, Также через функцию getCandlesByIndex нужно написать цикл, который будет перебирать свечки начиная с текущей и в прошлое, пока не найдет свечки фрактала.
Sergey Gorokhov написал: Здравствуйте, Также через функцию getCandlesByIndex нужно написать цикл, который будет перебирать свечки начиная с текущей и в прошлое, пока не найдет свечки фрактала.
t, n, l = getCandlesByIndex("qwe", 0, 0, getNumCandles("qwe")-1)
Up=false
Down=false
for i=0,n-1 do
num=n-1-i
if (t[num].high)>0 then
Up=true
message("Up=".. t[num].datetime.hour..":"..t[num].datetime.min)
end
if (t[num].low)>0 then
Down=true
message("Down=".. t[num].datetime.hour..":"..t[num].datetime.min)
end
if Up and Down then
break
end
end
t, n, l = getCandlesByIndex ( "qwe" , 0 , 0 , getNumCandles ( "qwe" ) - 1 )
Up = false
Down = false
for i = 0 ,n - 1 do
num = n - 1 - i
if (t[num].high) > 0 then
Up = true
message ( "Up=" .. t[num].datetime.hour .. ":" .. t[num].datetime.min)
end
if (t[num].low) > 0 then
Down = true
message ( "Down=" .. t[num].datetime.hour .. ":" .. t[num].datetime.min)
end
if Up and Down then
break
end
end
Что-то не получается. У меня график с часовым тайм-фреймом. Скрипт выдаёт время 11:45 и для верхнего и нижнего фрактала. Фракталов конечно же в это время там нет. В какую сторону копать?
предоставьте хоть какие-нибудь данные для анализа, скриншоты, Ваш код. голословно проблему никак не определить.
local N2 = getNumCandles(CODE_FRAC); t2,n2,i2 = getCandlesByIndex(CODE_FRAC, 0, 0, N2-1);
Up = false Down = false for i = 0, n - 1 do num = n - 1 - i if (t[num].high) > 0 then Up = true message("Up="..t[num].datetime.hour..":"..t[num].datetime.min,1) end if (t[num].low) > 0 then Down = true message("Down="..t[num].datetime.hour ..":".. t[num].datetime.min,1) end if Up and Down then break end end
Полный код более 1000 строк. CODE_FRAC = (io.open(getScriptPath().."\\files\\CODE_FRAC.txt","r")):read("*l"); Из этого файла читаем (все читается правильно) идентификатор. Во вкладке "дополнительно", индикатора фрактал прописано чётко тоже самое, что и в фале CODE_FRAC.
Вы можете создать маленький код, без всего лишнего, на котором воспроизвести проблему.
Сложно выковыривать нужное)) Поверьте скрипт рабочий, свечи, цены, другие индикаторы считываются правильно. Фракталы не идут(( Сейчас опять запустил - выдает нижний -12:00, верхний 12:00. Естественно там нет ничего, к тому же это текущая часовая свеча.