function NumberToRGB(number)
local number = tonumber(number) or 0
return bit.band(number,0x0000FF), bit.rshift(bit.band(number,0x00FF00),8), bit.rshift(bit.band(number,0xFF0000),16) -- R, G, B
end
У меня тоже больше не вылетает, плавающий Exception какой-то, больше ни разу не вылетел, может быть и не был связан с этой ошибкой. Но на этот раз эксперимент я сделал банально просто, результат можно посмотреть на видео ниже.
Что было сделано: берем пустую папку и распаковываем туда последний апдейт квика с FTP, на данный момент был "quik_7.9.1_upd.zip", далее в эту папку из рабочего квика переносим папку "Archives", в ней оставлены только данные по акции сбербанка для примера, также берем папку "LuaIndicators" с одним пользовательским индикатором и копируем файлы classes.dat, par.dat, sec.dat собственно чтобы в списке инструментов можно было найти график и отрисовать его данные из архива. То есть получается все файлы кроме "classes.dat, par.dat, sec.dat, папки LuaIndicators и папки archive" - это оригинальный апдейт последней версии.
Далее эксперимент по порядку как описывал выше, заметил что линии слетают даже при простом клонировании только что созданного и настроенного соответствующим образом графика, не только после операции выкл.-вкл.
Пока заливал видео, проверил еще несколько вариантов и кажется есть у меня одна догадка, походу рабочая, если после создания таким образом графика завершать диалог кнопкой "ОК" - то затем вся нарисованная от руки графика на таком графике будет слетать вниз, если нажимать сначала "Применить", потом "ОК", то однако все будет оставаться, в общем если из этого диалога всегда выходить комбинацией "Применить" затем "ОК", то все работает как надо ))
Отскриншотил все по порядку, никаких дополнительных настроек, все как есть (Win7): 1. Создаем новый график инструмента 2. Правый клик на нем, "Редактировать", жмем сразу сверху "Добавить" и выбираем, например, стандартный "Moving Average", опция "Поместить график в новую область" не установлена, нажимаем "Добавить", MA добавляется к области с "Price" 3. Снова нажимаем сверху "Добавить", выбираем пользовательский индикатор из LuaIndicators, для примера индикатор "Volume Moving Average", опция "Поместить график в новую область" установлена, нажимаем "Добавить" 4. В итоге получаем структуру индикаторов и областей как на изображении 5. Нажимаем "ОК" и получаем отрисованный график с областями и индикаторами 6. На области с ценой рисуем любые линии, тренды, области, затем выбираем пункт меню "Система" -> "Выход", программа закрывается 7. Снова запускаем программу (всегда запускаем от имени "Администратора"), после загрузки получаем все нарисованные линии, тренды и области сваленными в кашу и перемещенными на самую нижнюю область
для эксперимента скрипт "Volume Moving Average" тут:
Скрытый текст
Код
Settings = {
Name = "*Volume Moving Average",
round = "off",
Period = 10,
Metod = "EMA", --SMA, EMA, WMA, SMMA
line = {{
Name = "Volume MA",
Type = TYPE_LINE,
Color = RGB(255, 0, 0)
}
}
}
function Init()
func = vMA()
return #Settings.line
end
function OnCalculate(Index)
return func(Index, Settings)
end
function vMA()
local t_SMA = F_SMA()
local t_EMA = F_EMA()
local t_WMA = F_WMA()
local t_SMMA = F_SMMA()
return function(I, Fsettings, ds)
local Out = nil
local Fsettings=(Fsettings or {})
local P = (tonumber(Fsettings.Period) or 4)
local M = (Fsettings.Metod or "SMA")
local VT = "Volume"
local R = (Fsettings.round or "off")
if M == "SMA" then
Out = t_SMA(I, P, VT, ds, R)
elseif M == "EMA" then
Out = t_EMA(I, P, VT, ds, R)
elseif M == "WMA" then
Out = t_WMA(I, P, VT, ds, R)
elseif M == "SMMA" then
Out = t_SMMA(I, P, VT, ds, R)
else
Out = nil
end
return rounding(Out, R)
end
end
------------------------------------------------------------------
--Moving Average SMA, EMA, WMA, SMMA
------------------------------------------------------------------
--[[Simple Moving Average (SMA)
SMA = sum(Pi) / n
]]
function F_SMA()
local SMA_TMP={}
return function (I, Period, VType, ds, round)
local Out = nil
if I == 1 then
SMA_TMP={}
end
if I >= Period then
local sum = 0
for i = I-Period+1, I do
sum = sum +Value(i, VType, ds)
end
SMA_TMP[I] = sum/Period
if I > Period then Out = SMA_TMP[I-1] end
end
return rounding(Out,round)
end
end
--[[Exponential Moving Average (EMA)
EMAi = (EMAi-1*(n-1)+2*Pi) / (n+1)
]]
function F_EMA()
local EMA_TMP={}
return function(I, Period, VType, ds, round)
local Out = nil
if I == 1 then
EMA_TMP={}
EMA_TMP[I]=rounding(Value(I, VType, ds),round)
else
EMA_TMP[I]=rounding((EMA_TMP[I-1]*(Period-1)+2*Value(I, VType, ds)) / (Period+1),round)
end
if I > Period then
Out = EMA_TMP[I-1]
end
return rounding(Out,round)
end
end
--[[
William Moving Average (WMA)
( Previous WILLMA * ( Period - 1 ) + Data ) / Period
]]
function F_WMA()
local WMA_TMP={}
return function(I, Period, VType, ds, round)
local Out = nil
if I == 1 then
WMA_TMP={}
WMA_TMP[I]=rounding(Value(I, VType, ds),round)
else
WMA_TMP[I]=rounding((WMA_TMP[I-1]*(Period-1)+Value(I, VType, ds)) / Period,round)
end
if I > Period then
Out = WMA_TMP[I-1]
end
return rounding(Out,round)
end
end
--[[Smoothed Moving Average (SMMA)
SMMAi = (sum(Pi) - SMMAi-1 + Pi) / n
]]
function F_SMMA()
local SMMA_TMP={}
return function(I, Period, VType, ds, round)
local Out = nil
if I == 1 then
SMMA_TMP={}
end
if I >= Period then
local sum = 0
for i = I-Period+1, I do
sum = sum +Value(i, VType, ds)
end
if I == Period then
SMMA_TMP[I]=rounding((sum-Value(I, VType, ds)+Value(I, VType, ds)) / Period, round)
else
SMMA_TMP[I]=rounding((sum-SMMA_TMP[I-1]+Value(I, VType, ds)) / Period, round)
end
if I > Period then Out = SMMA_TMP[I-1] end
end
return rounding(Out,round)
end
end
function rounding(num, round)
if round and string.upper(round)== "ON" then round=0 end
if num and tonumber(round) then
local mult = 10^round
if num >= 0 then return math.floor(num * mult + 0.5) / mult
else return math.ceil(num * mult - 0.5) / mult end
else return num 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] else Out = nil end
end
return Out
end
Подтверждаю, на версии 7.7.0.89 которая сейчас у сбера, если в области с Price есть еще какой-либо индикатор, пользовательский или нет - не важно, главное что там их в области больше одного, если при этом создать дополнительную область с пользовательским индикатором из LuaIndicators - то при перезапуске вся графика(тренды, линии, метки...) нарисованная на области Price сваливается в окно с пользовательским индикатором, если после этого дальше пытаться манипулировать с пользовательскими индикаторами и областями на этом графике то может даже вылететь Exception