Блог им. grafta

Lua индикатор для Quik, Bollinger Bands %b Oscillator

Доброго времени всем.
Ищу Lua индикатор для Quik, Bollinger Bands %b (Bollinger Bands %BB Oscillator).  На MT4 есть в открытом виде. Возможно у кого-то уже есть переделанный в lua. Буду очень признателен в помощи его отыскать. Если не найду, придется переписывать самому в lua...(




Кому интересно, переделал индикатор Bollinger Bands (ВВ.lua) под осциллятор Bollinger Bands  %B   





Settings = {
Name = "*BB (Bollinger Bands) %B oscillator",
Period = 20,
Metod = «SMA», --(SMA, MMA, EMA, WMA, SMMA, VMA)
VType = «Close», --(Open, High, Low, Close, Volume, Median, Typical, Weighted, Difference)
Shift=2,
line = {{
Name = «Horizontal line (top)»,
Type = TYPE_LINE,
Color = RGB(221, 44, 44)
},
{
Name = «Horizontal line (bottom)»,
Type = TYPE_LINE,
Color = RGB(221, 44, 44)
},
{
Name = «Bollinger Bands %B oscillator line»,
Type = TYPE_LINE,
Color = RGB(255, 255, 255)
}
},
Round = «off»,
Multiply = 1,
Horizontal_line=«0»
}

function Init()
func = BB_B()
return #Settings.line
end

function OnCalculate(Index)
local Out = ConvertValue(Settings, func(Index, Settings))
local HL = tonumber(Settings.Horizontal_line)
if HL then
return 1+HL,HL,Out
else
return nil,nil,Out
end
end


function BB_B() --Bollinger Bands %B oscillator («BB_B»)
local BB_MA=MA()
local BB_SD=SD()
local it = {p=0, l=0}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 20)
local M = (Fsettings.Metod or SMA)
local S = (Fsettings.Shift or 2)
local VT = (Fsettings.VType or CLOSE)
if (P > 0) then
if I == 1 then
it = {p=0, l=0}
end

local b_ma = BB_MA(I, {Period=P, Metod = M, VType=VT}, ds)
local b_sd = BB_SD(I, {Period=P, Metod = SMA, VType=VT}, ds)
if CandleExist(I,ds) then
if I~=it.p then it={p=I, l=it.l+1} end
if it.l >= P and b_ma and b_sd then


if GetValueEX(it.p,VT,ds) ~= nil then

return ( GetValueEX(it.p,VT,ds) — (b_ma — S * b_sd)) / ((b_ma + S * b_sd) — (b_ma — S * b_sd))
— (Последняя цены – нижняя граница) / (верхняя граница — нижняя граница)

else
return 0
end


— return b_ma, b_ma + S * b_sd, b_ma — S * b_sd — возвращает среднюю, верхнюю, нижнию ВВ
end
end
end
return nil
end
end

 

function BB() --Bollinger Bands («BB»)
local BB_MA=MA()
local BB_SD=SD()
local it = {p=0, l=0}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 20)
local M = (Fsettings.Metod or SMA)
local S = (Fsettings.Shift or 2)
local VT = (Fsettings.VType or CLOSE)
if (P > 0) then
if I == 1 then
it = {p=0, l=0}
end
local b_ma = BB_MA(I, {Period=P, Metod = M, VType=VT}, ds)
local b_sd = BB_SD(I, {Period=P, Metod = SMA, VType=VT}, ds)
if CandleExist(I,ds) then
if I~=it.p then it={p=I, l=it.l+1} end
if it.l >= P and b_ma and b_sd then
return b_ma, b_ma + S * b_sd, b_ma — S * b_sd
end
end
end
return nil,nil,nil
end
end

function SD() --Standard Deviation («SD»)
local SD_MA=MA()
local sum = {}
local sum2 = {}
local it = {p=0, l=0}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 20)
local M = (Fsettings.Metod or SMA)
local VT = (Fsettings.VType or CLOSE)
if (P>0) then
if I == 1 then
sum = {}
sum2 = {}
it = {p=0, l=0}
end
local t_ma = SD_MA(I, {Period=P, Metod = M, VType=VT}, ds)
if CandleExist(I,ds) then
if I~=it.p then it={p=I, l=it.l+1} end
local Ip,Ipp,Ippp = Squeeze(it.l,P),Squeeze(it.l-1,P),Squeeze(it.l-P,P)
sum[Ip]=(sum[Ipp] or 0) + GetValueEX(it.p, VT, ds)
sum2[Ip]=(sum2[Ipp] or 0) + GetValueEX(it.p, VT, ds)^2
if it.l >= P and t_ma then
return math.sqrt((sum2[Ip]-(sum2[Ippp] or 0) — 2*t_ma*(sum[Ip]-(sum[Ippp] or 0)) + P*(t_ma^2)) / P)
end
end
end
return nil
end
end

function MA() --Moving Average («MA»)
local T_MA = {[SMA]=F_SMA(),[MMA]=F_MMA(),[EMA]=F_EMA(),[VMA]=F_VMA(),[SMMA]=F_SMMA(),[WMA]=F_WMA()}
return function (I, Fsettings, ds)
local Fsettings=(Fsettings or {})
local P = (Fsettings.Period or 14)
if (P > 0) then
return T_MA[string.upper(Fsettings.Metod or EMA)](I, P, (Fsettings.VType or CLOSE), ds)
end
return nil
end
end

------------------------------------------------------------------
----Moving Average SMA, MMA, EMA, WMA, SMMA, VMA
------------------------------------------------------------------
--[[Simple Moving Average (SMA)
SMA = sum(Pi) / n]]
function F_SMA()
local sum = {}
local it = {p=0, l=0}
return function (I, P, VT, ds)
if I == 1 then
sum = {}
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then it={p=I, l=it.l+1} end
local Ip,Ipp,Ippp = Squeeze(it.l,P),Squeeze(it.l-1,P),Squeeze(it.l-P,P)
sum[Ip] = (sum[Ipp] or 0) + GetValueEX(it.p,VT,ds)
if it.l >= P then
return (sum[Ip] — (sum[Ippp] or 0)) / P
end
end
return nil
end
end

--[[Modified Moving Average (MMA)
MMA = (MMAi-1*(n-1) + Pi) / n]]
function F_MMA()
local sum = {}
local tmp = {pp=nil, p=nil}
local it = {p=0, l=0}
return function(I, P, VT, ds)
if I == 1 then
sum = {}
tmp = {pp=nil, p=nil}
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then
it = {p=I, l=it.l+1}
tmp.pp = tmp.p
end
local Ip,Ipp,Ippp = Squeeze(it.l,P),Squeeze(it.l-1,P),Squeeze(it.l-P,P)
if it.l <= P + 1 then
sum[Ip] = (sum[Ipp] or 0) + GetValueEX(it.p,VT,ds)
if (it.l == P) or (it.l == P + 1) then
tmp.p = (sum[Ip] — (sum[Ippp] or 0)) / P
end
else
tmp.p = (tmp.pp*(P-1) + GetValueEX(it.p,VT,ds)) / P
end
if it.l >= P then
return tmp.p
end
end
return nil
end
end

--[[Exponential Moving Average (EMA)
EMAi = (EMAi-1*(n-1)+2*Pi) / (n+1)]]
function F_EMA()
local tmp = {pp=nil, p=nil}
local it = {p=0, l=0}
return function(I, P, VT, ds)
if I == 1 then
tmp = {pp=nil, p=nil}
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then
it = {p=I, l=it.l+1}
tmp.pp = tmp.p
end
if it.l == 1 then
tmp.p = GetValueEX(it.p,VT,ds)
else
tmp.p = (tmp.pp*(P-1) + 2*GetValueEX(it.p,VT,ds)) / (P+1)
end
if it.l >= P then
return tmp.p
end
end
return nil
end
end

--[[
William Moving Average (WMA)
( Previous WILLMA * ( Period — 1 ) + Data ) / Period]]
function F_WMA()
local tmp = {pp=nil, p=nil}
local it = {p=0, l=0}
return function(I, P, VT, ds)
if I == 1 then
tmp = {pp=nil, p=nil}
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then
it={p=I, l=it.l+1}
tmp.pp = tmp.p
end
if it.l == 1 then
tmp.p = GetValueEX(it.p,VT,ds)
else
tmp.p = (tmp.pp * (P-1) + GetValueEX(it.p,VT,ds)) / P
end
if it.l >= P then
return tmp.p
end
end
return nil
end
end

--[[Volume Adjusted Moving Average (VMA)
VMA = sum(Pi*Vi) / sum(Vi)]]
function F_VMA()
local sum = {}
local sum2 = {}
local it = {p=0, l=0}
return function(I, P, VT, ds)
if I == 1 then
sum = {}
sum2 = {}
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then it={p=I, l=it.l+1} end
local Ip,Ipp,Ippp = Squeeze(it.l,P),Squeeze(it.l-1,P),Squeeze(it.l-P,P)
sum[Ip] = (sum[Ipp] or 0) + GetValueEX(it.p,VT,ds) * GetValueEX(it.p,VOLUME,ds)
sum2[Ip] = (sum2[Ipp] or 0) + GetValueEX(it.p,VOLUME,ds)
if it.l >= P then
return (sum[Ip] — (sum[Ippp] or 0)) / (sum2[Ip] — (sum2[Ippp] or 0))
end
end
return nil
end
end

--[[Smoothed Moving Average (SMMA)
SMMAi = (sum(Pi) — SMMAi-1 + Pi) / n]]
function F_SMMA()
local sum = {}
local sum2 = {}
local it = {p=0, l=0}
return function(I, P, VT, ds)
if I == 1 then
sum = {}
sum2 = {}
it = {p=0, l=0}
end
if CandleExist(I,ds) then
if I~=it.p then it={p=I, l=it.l+1} end
local Ip,Ipp,Ippp = Squeeze(it.l,P),Squeeze(it.l-1,P),Squeeze(it.l-P,P)
sum[Ip] = (sum[Ipp] or 0) + GetValueEX(it.p,VT,ds)
if it.l >= P then
if it.l == P then
sum2[Ip] = (sum[Ip] — (sum[Ippp] or 0)) / P
else
sum2[Ip] = ((sum[Ip] — (sum[Ippp] or 0)) — (sum2[Ipp] or 0)+ GetValueEX(it.p,VT,ds)) / P
end
return sum2[Ip]
end
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©==«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®== «ON» then R=0 end
if V and tonumber® 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
local arg = {...}
arg.n = select('#', ...)
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

Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
  • обсудить на форуме:
  • Quik Lua
| ★2
4 комментария
Сергей Сергаев, Спасибо за ссылку, но там нет, увы ( только Bollinger Bands (ВВ.lua)
avatar
Кому интересно, переделал индикатор Bollinger Bands (ВВ.lua) под осциллятор Bollinger Bands  %B  


avatar

Читайте на SMART-LAB:
Фото
Самый подробный разбор отчета БАЗИСа из всех, которые вы могли прочесть + что я нашел!!!
Что я сделал? ✅Просмотрел вебкаст с менеджментом ✅Изучил пресс-релиз ✅Изучил отчет за 1 квартал ✅эфир с Ириной Диденко у Максима...
Обновление кредитных рейтингов в ВДО и розничных облигациях (ГУП "ЖКХ РС (Я)" подтвержден ruC, ПАО «АПТЕЧНАЯ СЕТЬ 36,6» подтвержден BBB+(RU))
⚪️ГУП «ЖКХ РС (Я)» Эксперт РА подтвердил кредитный рейтинг на уровне ruС и снял статус «под наблюдением», прогноз по рейтингу развивающийся....
Инвестиции без спешки: торгуем в выходные
Дмитрий Пучкарев Рынок часто движется импульсами, тем важнее оценивать активы без спешки, не отвлекаясь на инфошум. Для этого отлично подходят...
Фото
Хэдхантер. Отчет МСФО за Q1 2026г. Всё будет непросто…но…есть надежда.
Вышли финансовые результаты по МСФО за Q1 2026г. от компании Хэдхантер: 👉Выручка — 9,49 млрд руб. (-1,5% г/г) 👉Операционные расходы —...

теги блога Grafta

....все тэги



UPDONW
Новый дизайн