--KeltnerChannel.lua, ver.1.4 © hismatullin.h@gmail.com, 28.10.2015
local math_floor = math.floor
local table_insert = table.insert
local math_abs = math.abs
local math_max = math.maxfunction dValue(index, v_type)
v_type = v_type or «C»
if v_type == «O» then
return O(index)
elseif v_type == «H» then
return H(index)
elseif v_type == «L» then
return L(index)
elseif v_type == «C» then
return C(index)
elseif v_type == «V» then
return V(index)
elseif v_type == «M» then
return (H(index) + L(index))/2
elseif v_type == «T» then
return (H(index) + L(index)+C(index))/3
elseif v_type == «W» then
return (H(index) + L(index)+2*C(index))/4
else
return C(index)
end
endSettings =
{
Name = «Keltner Channel»,
PeriodEMA = 3,
PeriodATR = 10,
K = 0.6,
value_type = «C»,
line=
{
{
Name = «MA»,
Color = RGB(0, 128, 0),
Type = 1,
Width = 1
},
{
Name = «MA+»,
Color = RGB(0, 0, 255),
Type = TYPE_LINE,
Width = 1
},
{
Name = «MA-»,
Color = RGB(0, 0, 255),
Type = TYPE_LINE,
Width = 1
}
}
}
function Init()
message([[Keltner Channel, ver.1.4 © hismatullin.h@gmail.com, 28.10.2015]], 1)
return 3
end
function average(_start, _end)
local sum=0
local l0 = 0
for i = _start, _end do
l0 = dValue(i, Settings.value_type)
sum=sum+l0
end
return sum/Settings.Period
endfunction round(value)
return math_floor(value / step + 0.5) * step
endfunction TrHighest(index)
local max_table = {}
table_insert(max_table, math_abs(H(index)-L(index)))
table_insert(max_table, math_abs(H(index)-C(index-1)))
table_insert(max_table, math_abs(C(index-1)-L(index)))
return math_max(unpack(max_table))
end
tr = {}
trEma = {}
cEma = {}
local per = 0function average(_start, _end)
local sum=0
for i = _start, _end do
sum=sum + tr[i]
end
return sum/(_end-_start+1)
end— нужен для начального расчета ЕМА
function averageC(_start, _end)
local sum=0
local l0 = 0
for i = _start, _end do
l0 = dValue(i, Settings.value_type)
sum=sum+l0
end
return sum/(_end-_start+1)
end
function trEMA(ind, _p)
local period = _p
local index = ind
if index <= period then
trEma[index] = average(1,index)
--message(«trEma[»..index.."] "..tostring(trEma[index]),3)
--return nil --trEma[index]
return trEma[index]
end
local n = (trEma[index-1]*(period-1) + tr[index])/period
trEma[index] = n
return n
end
function averageEMA(ind, _p)
local n = 0
local p = 0
local period = _p
local index = ind
local k = 2/(period+1)
local l0 = dValue(index, Settings.value_type)
if index < period then
cEma[index] = averageC(1,index)
return cEma[index]
--nil
end
p = cEma[index-1] or l0
n = k*l0+(1-k)*p
cEma[index] = n
return n
end
function OnCalculate(index)
if index == 1 then
t=getDataSourceInfo()
tr[index]=H(index)-L(index)
step = getSecurityInfo(t.class_code, t.sec_code).min_price_step --NUMBER, Минимальный шаг цены
per = math_max(Settings.PeriodEMA, Settings.PeriodATR)
--message(t.sec_code..", интервал="..t.interval..', step= '..step,1)
else
tr[index]=TrHighest(index)
endlocal _sma = averageEMA(index, Settings.PeriodEMA)
_sma = round(_sma)
local _atr = trEMA(index, Settings.PeriodATR)
if index < per then
return nil
endlocal delta = round(_atr*Settings.K)
local _low = _sma-delta
local _high = _sma+delta
return _sma, _high, _low
end
В коде французские кавычки («ёлочки») должны быть переделаны в тексте выше в «английские двойные» либо в 'английские одиночные' — особенности сайта...
увидел интересный топик про каналы кельтнера, поставил все возможные плюсы.
вопрос появился: там в основе лежит EMA,
а есть ли версия с SMA?
Благодарю за труд!
С некоторыми индикаторами обычно происходит так: сделал, опубликовал, забыл. С этим также.
Примите как есть, если что нужно сделать — сами.
К тому же, на SMA переделать проще с EMA, чем наоборот.
Но когда код в глаза не видел с института — это становится не такой простой задачей. )
Можно ли каким-то примитивным образом, задав коэффициент в виде единицы или просто заменив одну переменную в расчетах превратить в SMA, чтобы весь остальной код вообще не править? Ваша подсказка будет очень кстати.
В любом случае, спасибо за труд!
ПС. Привет Стерлитамаку!
Переделать на SMA — для меня сильно-сильно влом (((