{PRICE,1,low} <= {PRICE_CHANNEL,lower} реагирует на обе линии и {PRICE,1,hi} >= {RTS_PRICE_CHANNEL,upper} то же самое, ловит обе линии, может вместо upper и lower что-то другое вводить?
Здравствуйте. Пытаюсь получить скриптом данные индикатора Price Channel
local DPC=getNumCandles(indic_graph_id) DPC_t,DPC_n,DPC_i=getCandlesByIndex(indic_graph_id, 0, DPC-3, 2) --забираем таблицу значений для двух предыдущих значений DPC message(tostring(dump(DPC_t[0])))
И выдаются значения только для верхней границы диапазона.
И второй вопрос - если использовать не встроенный индикатор, а тот, который вы предлагаете в архиве (он со звездочкой) отдельным файлом, то он при запросе скриптом выдает все значения цены нулевые.
Олег написал: Для внешнего индикатора (архив на скачивание выше):
В скрипте это легко меняется. Указать так: function OnCalculate(Index) return ConvertValue(Settings, func(Index, Settings)),tonumber(Settings.Horizontal_line) end
function PC() --Price Channel ("PC") --какойтокод return val_h,(val_h+val_l)/2,val_l --какойтокод end
Олег написал: Для внешнего индикатора (архив на скачивание выше):
В скрипте это легко меняется. Указать так: function OnCalculate(Index) return ConvertValue(Settings, func(Index, Settings)),tonumber(Settings.Horizontal_line) end
function PC() --Price Channel ("PC") --какойтокод return val_h,(val_h+val_l)/2,val_l --какойтокод end
Тогда индикатор отрисовывает только одну верхнюю линию. Надо еще что-то менять.
Можно получить комментарий что возвращает (ниже) это выражение в Price Channel? Линий же должно быть три? Что то не разберусь. Как одно выражение дает три значения? tonumber(Settings.Horizontal_line), ConvertValue(Settings, func(Index, Settings))
Олег написал: Тогда индикатор отрисовывает только одну верхнюю линию. Надо еще что-то менять.
Да Вы правы, надо удалить отрисовку горизонтальной линии. Т.е. так: function OnCalculate(Index) return ConvertValue(Settings, func(Index, Settings)),tonumber(Settings.Horizontal_line) end если она все же нужна то ее можно добавлять только первой.
полный код под спойлером
Скрытый текст
Код
Settings = {
Name = "*PC (Price Channel)",
Period = 10,
line = {
{
Name = "PC - upper",
Type = TYPE_LINE,
Color = RGB(0, 206, 0)
},
{
Name = "PC",
Type = TYPE_LINE,
Color = RGB(221, 44, 44)
},
{
Name = "PC - lower",
Type = TYPE_LINE,
Color = RGB(0, 162, 232)
}
--[[,
{
Name = "Horizontal line",
Type = TYPE_LINE,
Color = RGB(140, 140, 140)
}]]
},
Round = "off",
Multiply = 1,
Horizontal_line="off"
}
function Init()
func = PC()
return #Settings.line
end
function OnCalculate(Index)
--return tonumber(Settings.Horizontal_line), ConvertValue(Settings, func(Index, Settings))
return ConvertValue(Settings, func(Index, Settings))
end
function PC() --Price Channel ("PC")
local H_tmp={}
local L_tmp={}
local it = {p=0, l=0}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 10)
if (P>0) then
if I == 1 then
H_tmp={}
L_tmp={}
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then it={p=I, l=it.l+1} end
H_tmp[Squeeze(it.l,P-1)+1] = GetValueEX(it.p,HIGH,ds)
L_tmp[Squeeze(it.l,P-1)+1] = GetValueEX(it.p,LOW,ds)
if it.l >= P then
local val_h = math.max(unpack(H_tmp))
local val_l = math.min(unpack(L_tmp))
return val_h,(val_h+val_l)/2,val_l
--return (val_h+val_l)/2,val_h,val_l
end
end
end
return nil,nil,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
Sergey Gorokhov, Можно из функции ниже получить нужное значение. Например val_h. Он же сюда возвращается из PC() . ConvertValue(Settings, func(Index, Settings)) ?
Олег написал: Тогда индикатор отрисовывает только одну верхнюю линию. Надо еще что-то менять.
Да Вы правы, надо удалить отрисовку горизонтальной линии. Т.е. так: function OnCalculate(Index) return ConvertValue(Settings, func(Index, Settings)),tonumber(Settings.Horizontal_line) end если она все же нужна то ее можно добавлять только первой.
полный код под спойлером Скрытый текст
Код
Settings = {
Name = "*PC (Price Channel)" ,
Period = 10 ,
line = {
{
Name = "PC - upper" ,
Type = TYPE_LINE,
Color = RGB ( 0 , 206 , 0 )
},
{
Name = "PC" ,
Type = TYPE_LINE,
Color = RGB ( 221 , 44 , 44 )
},
{
Name = "PC - lower" ,
Type = TYPE_LINE,
Color = RGB ( 0 , 162 , 232 )
}
--[[,
{
Name = "Horizontal line" ,
Type = TYPE_LINE,
Color = RGB ( 140 , 140 , 140 )
}]]
},
Round = "off" ,
Multiply = 1 ,
Horizontal_line = "off"
}
function Init ()
func = PC()
return # Settings.line
end
function OnCalculate (Index)
--return tonumber(Settings.Horizontal_line), ConvertValue(Settings, func(Index, Settings))
return ConvertValue(Settings, func(Index, Settings))
end
function PC () --Price Channel ("PC")
local H_tmp = {}
local L_tmp = {}
local it = {p = 0 , l = 0 }
return function (I, Fsettings, ds)
local Fsettings = (Fsettings or {})
local P = (Fsettings.Period or 10 )
if (P > 0 ) then
if I = = 1 then
H_tmp = {}
L_tmp = {}
it = {p = 0 , l = 0 }
end
if CandleExist(I,ds) then
if I~ = it.p then it = {p = I, l = it.l + 1 } end
H_tmp[Squeeze(it.l,P - 1 ) + 1 ] = GetValue EX(it.p,HIGH,ds)
L_tmp[Squeeze(it.l,P - 1 ) + 1 ] = GetValue EX(it.p,LOW,ds)
if it.l > = P then
local val_h = math.max (unpack(H_tmp))
local val_l = math.min (unpack(L_tmp))
return val_h,(val_h + val_l)/ 2 ,val_l
--return (val_h+val_l)/2,val_h,val_l
end
end
end
return nil , nil , 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 (( GetValue EX(I,HIGH,ds) + GetValue EX(I,LOW,ds)) / 2 )
elseif VT = = TYPICAL then --Typical
return (( GetValue EX(I,MEDIAN,ds) * 2 + GetValue EX(I,CLOSE,ds))/ 3 )
elseif VT = = WEIGHTED then --Weighted
return (( GetValue EX(I,TYPICAL,ds) * 3 + GetValue EX(I,OPEN,ds))/ 4 )
elseif VT = = DIFFERENCE then --Difference
return ( GetValue EX(I,HIGH,ds) - GetValue EX(I,LOW,ds))
else --Any
return (ds and ds[I])
end
return nil
end
Скажите, почему при применении данного индикатора значения его линий отдаются в скрипт после прорисовки 3-го (третьего) бара дня. Например, если график у нас 15-ти минутки, то он отдаст значения своих линий только с 10.30, а до этого с 10.00 значения линий будут нулевыми.
Скажите, почему при применении данного индикатора значения его линий отдаются в скрипт после прорисовки 3-го (третьего) бара дня. Например, если график у нас 15-ти минутки, то он отдаст значения своих линий только с 10.30, а до этого с 10.00 значения линий будут нулевыми.
да, и у меня индикатор сдвинут на 1 бар вперёд, то есть если не сдвигать, то нулевые значения будут на первом баре открытия, а со второго все норм. В чем проблема?
Олег написал: Тогда индикатор отрисовывает только одну верхнюю линию. Надо еще что-то менять.
Да Вы правы, надо удалить отрисовку горизонтальной линии. Т.е. так: function OnCalculate(Index) return ConvertValue(Settings, func(Index, Settings)),tonumber(Settings.Horizontal_line) end если она все же нужна то ее можно добавлять только первой.
полный код под спойлером
Проблема в получении значений линий индикатора на втором баре торговой сессии - все значения нулевые. Например, если график 15-минутный, то до 10.15 значения индикатора верные, потом с 10.15 до 10.30 нулевые, а потом снова все Ок и до конца сессии. В чем проблема может быть? Причем если сделать двойной клик на область диаграммы, где этот индикатор, то есть откроется меню "Редактирование настроек графика", а потом ничего не меняя нажать Ок, то значения линий индикатора в скрипте сразу появятся - чудеса...