package.path = package.path .. ";" .. getWorkingFolder() .."\\LuaIndicators\\modules\\" .. "?.lua";
require ("Format");
require ("Round");
--require ("Lines");
Settings={
Name = "0_11.03.2019",--имя индикатора
AssetID = "sber",--идентификатор иструмента
LabelName = "D:\метка.bmp",--имя файла метки "down-254095_1280_1",
stopper = false,--обработка на каждом тике
complect = 0,
-- начальное местоположение меток
fplace = 110,
splace = 8,
thplase = 30,
Yvalue = 0,
line=
{
{
Name = "ChTrnd",
Type =TYPE_LINE,
Width = 2,
Color = RGB(255,255, 0)
},
{
Name = "UpTrend",
Type =TYPE_LINE,
Width = 2,
Color = RGB(0,255,0)
},
{
Name = "DnTrend",
Type =TYPE_LINE,
Width = 2,
Color = RGB(0,255, 0)
},
{
Name = "APointLvl",
Type =TYPE_LINE,
Width = 1,
Color = RGB(120,90,140)
},
{
Name = "BPointLvl",
Type =TYPE_LINE,
Width = 1,
Color = RGB(120,90,140)
},
{
Name = "IntLine1",
Type =TYPE_LINE,
Width = 2,
Color = RGB(105,105,105)--DimGray
},
{
Name = "IntLine2",
Type =TYPE_LINE,
Width = 2,
Color = RGB(0,0,255)--Blue
},
{
Name = "IntLine3",
Type =TYPE_LINE,
Width = 2,
Color = RGB(218,165,32)--Goldenrod
},
{
Name = "IntLine4",
Type =TYPE_LINE,
Width = 2,
Color = RGB(255,0,0)--Red
},
{
Name = "IntLine5",
Type =TYPE_LINE,
Width = 2,
Color = RGB(0,128,0)--Green
},
{
Name = "IntLine6",
Type =TYPE_POINT,
Width = 1,
Color = RGB(255,0,0)--Red
},
{
Name = "fLine1",
Type =TYPE_LINE,
Width = 1,
Color = RGB(120,90,140)
},
{
Name = "fLine2",
Type =TYPE_LINE,
Width = 1,
Color = RGB(120,90,140)
},
{
Name = "ChannelFormingZone",
Type =TYPE_HISTOGRAM,
Width = 1,
Color = RGB(255,255, 0)
},
{
Name = "pLine1",
Type =TYPE_LINE,
Width = 1,
Color = RGB(120,90,140)
},
{
Name = "pLine2",
Type =TYPE_LINE,
Width = 1,
Color = RGB(120,90,140)
},
{
Name = "ChannelActionZone",
Type =TYPE_HISTOGRAM,
Width = 1,
Color = RGB(255,255, 0)
},
{
Name = "ChannelActionZone",
Type =TYPE_HISTOGRAM,
Width = 1,
Color = RGB(255,255, 0)
},
{
Name = "ExtLine1",
Type =TYPE_POINT,
Width = 1,
Color = RGB(0,255,255)--Aqua
},
{
Name = "ExtLine2",
Type =TYPE_POINT,
Width = 1,
Color = RGB(0,255,255)--Aqua
},
{
Name = "ExtLine3",
Type =TYPE_POINT,
Width = 1,
Color = RGB(0,255,255)--Aqua
},
{
Name = "ExtLine4",
Type =TYPE_POINT,
Width = 1,
Color = RGB(0,255,255)--Aqua
},
{
Name = "ExtLine5",
Type =TYPE_POINT,
Width = 1,
Color = RGB(0,255,255)--Aqua
},
{
Name = "ExtLine6",
Type =TYPE_POINT,
Width = 1,
Color = RGB(0,255,255)--Aqua
},
{
Name = "ChTrndExt",
Type =TYPE_POINT,
Width = 1,
Color = RGB(120,90,140)--Aqua
},
{
Name = "ChUpExt",
Type =TYPE_POINT,
Width = 1,
Color = RGB(120,90,140)--Aqua
},
{
Name = "ChDnExt",
Type =TYPE_POINT,
Width = 1,
Color = RGB(120,90,140)--Aqua
}
}
}
--глобальные переменные
-- Внимание, название всех параметров меток должны писаться большими буквами
label={
--TEXT="метка";
IMAGE_PATH=Settings.LabelName;
--TRANSPARENCY=50,
--TRANSPARENT_BACKGROUND=1,
--YVALUE=Settings.Yvalue,
DATE=0,
TIME=0;
--R=255;
--G=255;
--B=255;
}
t={}--исходная таблица данных свечек
tposixByTime={}--индексы свечек проиндексированные по времени
tposixOldLabelTime={}--таблица старых значений даты-времени выведенных на чарт меток в POSIX-формате
count=0--ограничитель количества циклов
Label_Id = {}--массив с идентификаторами меток
ScriptPath=""--полный путь к иконке (для метки)
flagIndExist=false--флаг существования индикатора на чарте
flagLblModify=false--флаг, сигнализирующий о перемещении метки
a=0
b=0
c=0
k=0
v=0
tDT={}
g_PriceStep = 0--шаг цены
g_PriceScale = 0--точность цены
g_tChLines={}
g_APointIdx=0;
g_BPointIdx=0;
g_APointLvl=0;
g_BPointLvl=0;
function Init()
--объявление переменных. Присваиваем начальные значения чтобы сразу типизировать.
local n = 0--количество строк в таблице (количество свечек)
local l = ""--подпись инструмента
local NmbrOfCandles = 0--номер последней справа свечи на графике
local CandleIndex = 0
--local tDT={}
---[[
if Settings.AssetID == "" then
message("Необходимо установить идентификатор инструмента")
end
--ScriptPath = getScriptPath().."\\"..Settings.LabelName; --путь к файлу метки
--message("Init_ScriptPath "..ScriptPath);
--label["IMAGE_PATH"]=ScriptPath;
--номер предпоследней справа свечи на графике. Нумерация начинается с нуля.
NmbrOfCandles = getNumCandles(Settings.AssetID)-2;
--получим таблицу с данными всех свечек, проиндексированную по номеру свечки
--t - таблица значений свечек
--n - количество полученных свечек(строк таблицы)
--l - подпись к инструменту
--текущую свечу не получаем
t,n,l = getCandlesByIndex(Settings.AssetID,0,0,NmbrOfCandles);
--[[
for i=0, NmbrOfCandles-1 do
message("Init_t "..tostring(t[i].high))
end
--]]
--получить индекс двух свечек, номера которых заданы во входных параметрах
--и установить метки
CandleIndex = NmbrOfCandles-Settings.splace;
tposixOldLabelTime["splace"], Label_Id["splace"] = PUTLABEL(CandleIndex);
CandleIndex = NmbrOfCandles-Settings.fplace;
tposixOldLabelTime["fplace"], Label_Id["fplace"] = PUTLABEL(CandleIndex);
CandleIndex = NmbrOfCandles-Settings.thplase;
tposixOldLabelTime["thplase"], Label_Id["thplase"] = PUTLABEL(CandleIndex);
--берем из таблицы только время-дату свечи
count = 0;
for k=0,NmbrOfCandles-1 do
count = count + 1; if count > 100000 then break end;
--преобразуем в POSIX-формат поле datetime
--транспонируем таблицу - индексируем по времени
tDT[k] = os.time (t[k].datetime);
tposixByTime[tDT[k]] = k;
end
--message("Init_tposixByTime_"..tostring(tDT[Size()-5]))--1539075600
--message("Init_tposixByTime_"..tostring(tDT[1550826000]))
return 27
end
function OnCalculate(index)
local info={}
local CandleIndex
local LblIdF = 0
local LblIdS = 0
local indput
local IndLines={}
local VChTrend
local VAPointLvl
local VBPointLvl
local flagIndChange=false--true-перестроить индикатор, false - не перестраивать
if index==1 then
info = getDataSourceInfo();
--шаг цены
g_PriceStep = getParamEx(info.class_code, info.sec_code, 'SEC_PRICE_STEP').param_value
--точность цены
g_PriceScale = getParamEx(info.class_code, info.sec_code, 'SEC_SCALE').param_value
end
---[[
--если флаг перемещения метки не установлен
if flagLblModify==false then
--message("OnCalculate_flagLblModify_"..tostring(flagLblModify))
--проверяем перемещалась ли первая метка
LblIdF=IsLabelChange("fplace");
--проверяем вторую метку
LblIdS=IsLabelChange("splace");
--если индикатор существует, то выходим без расчетов, возвращаем массив линий
if flagIndExist==true then
flagIndChange=false;
--иначе строим индикатор, возвращаем массив линий
else
flagIndChange=true;
end
--если метка перемещалась flagLblModify==true
else
--строим индикатор, выставляем флаг изменения индикатора,
--сбрасываем флаг метки, возвращаем индикатор
flagIndChange=true;
LblIdF=Label_Id.fplace
LblIdS=Label_Id.splace
end
--message("OnCalculate_flagLblModify_"..tostring(flagLblModify))
--message("OnCalculate_LblIdF_"..tostring(LblIdF).." "..tostring(LblIdS))
--рассчитываем индикатор или выводим линии без расчета
VChTrend,VChUp,VChDn,VAPointLvl,VBPointLvl,VIntLine1=PUTINDICATOR(LblIdF,LblIdS,flagIndChange,index)
--]]
if index==0 then VChTrend=nil end
if index >= Size() then VChTrend=nil end
return VChTrend,VChUp,VChDn,VAPointLvl,VBPointLvl,VIntLine1,VIntLine2,VIntLine3,VIntLine4,VIntLine5,VIntLine6,VfLine1,VfLine2,VFormingTime,VpLine1,VpLine2,VActionTme,VActionTime,VExtLine1,VExtLine2,VExtLine3,VExtLine4,VExtLine5,VExtLine6,VChTrndExt,VChUpExt,VChDnExt
end
function IsLabelChange(place)
--функция принимает индекс массива Label_Id("строка")
--устанавливает глобальные флаги и
--записывает posix-время в глобальную таблицу tposixOldLabelTime
--возврашает Id метки
local LblId = 0
local posixNewLblTime = 0
local posixOldLblTime = 0
--проверяем перемещалась ли метка
--считываем Id метки из массива
LblId = Label_Id[place];
--message("IsLabelChange_LabelId_"..tostring(place))
--считываем posix-время для этой метки
posixOldLblTime = tposixOldLabelTime[place];
--преобразуем время метки с чарта в posix-формат
--если функция вернула nil, время не меняем
if GETLABLEPOSIXTIME (LblId)== 0 then
posixNewLblTime = posixOldLblTime
else
posixNewLblTime = GETLABLEPOSIXTIME (LblId)
end
--если время не совпадает, выставляем флаги отсутствия индикатора и модификации метки
if posixOldLblTime ~= posixNewLblTime then
--выставляем флаги
--метка перемещена
flagLblModify=true;
--индикатор не построен
flagIndExist=false;
--изменяем время метки в массиве
tposixOldLabelTime[place] = posixNewLblTime;
end
return LblId
end
PUTLABEL = function (index)
--[[функция для установки метки на чарт по индексу
принимает индекс свечи
возвращает время метки в posix-формате и Id метки
входные параметры:
-индекс свечи
-строка с названием точки для индексации массива установленных меток
вызывается в Init()
--]]
local Date=""--дата свечки
local Time=""--время свечки
local Yvalue=0
LabelId=0
--message ("PUTLABEL_index.."..tostring(index));
--дата и время свечи
Date=t[index].datetime.year..Format.FTEXT(t[index].datetime.month)..Format.FTEXT(t[index].datetime.day); --дата
Time=Format.FTEXT(t[index].datetime.hour)..Format.FTEXT(t[index].datetime.min)..Format.FTEXT(t[index].datetime.sec);
--привязка к оси У
Yvalue = t[index].high;
--заполнить структуру данных метки
label={
IMAGE_PATH=Settings.LabelName;
YVALUE=Settings.Yvalue+Yvalue;
DATE=Date,
TIME=Time
};
--добавляем метку на чарт и запоминаем Id метки в массиве, проиндексированном принятой строкой
LabelId = AddLabel(Settings.AssetID,label);
--message ("PUTLABEL LabelId "..tostring(LabelId).." "..tostring(os.time (t[index].datetime)))
return os.time (t[index].datetime), LabelId
end
function GETLABLEPOSIXTIME (LabelId)
--функция принимает Id метки и возвращает ее время в posix-формате
--при перемещении метки временно Id может стать нулем, поэтому функция выдает ошибку ноль
local id--Id метки
local NewLbLParam = {}--структура параметров метки
local LabelTime = ""--строка с данными даты-времени метки
local dt={}--структура в формате datetime
local err=0
local retval
---[[
id = LabelId;
--message("GETLABLEPOSIXTIME_LabelId_"..tostring(LabelId))
--получаем таблицу с параметрами метки (в нижнем регистре в формате строки)
if LabelId==0 then retval=err
else
NewLbLParam = GetLabelParams(Settings.AssetID, id);
--преобразуем в формат datetime
dt.year,dt.month,dt.day = string.match(NewLbLParam.date,"(%d%d%d%d)(%d%d)(%d%d)")
if #NewLbLParam.time == 5 then
LabelTime="0".. NewLbLParam.time
else LabelTime="".. NewLbLParam.time
end
if tostring(NewLbLParam.time)=="0" then
LabelTime="000000"
end
dt.hour,dt.min,dt.sec = string.match(LabelTime,"(%d%d)(%d%d)(%d%d)");
--преобразуем в формат POSIX
retval = os.time (dt)
end;
return retval;
end
function PUTINDICATOR(LblId1,LblId2,boolIndChange,idx)
local a=0
local i
local j
local k
local TrndH=0
local TrndL=0
local h
local l
local CndlIdx1=0
local CndlIdx2=0
local tABIdx={}
local IntervalCndlNmbr=0
local koef
local p1koef
local p2koef
local tChTrend={}
local tChUp={}
local tChDn={}
local ChUpMax=0
local ChDnMin=0
local posixLblTime1
local posixLblTime2
local APointIdx
local BPointIdx
local APointLvl
local BPointLvl
local idxUpMax
local idxDnMin
local AidxUp
local AidxDn
local BidxUp
local BidxDn
local ChTrnd
local ChUp
local ChDn
local APntLvl
local BPntLvl
local StepsUp
local TrUp=false
local TrDn=false
local Lu
local tfLine1={}
local tfLine2={}
local tpLine1={}
local tpLine2={}
local Aidx
local Bidx
g_tChLines["ChTrend"]=tChTrend;
g_tChLines["ChUp"]=tChUp;
g_tChLines["ChDn"]=tChDn;
g_tChLines["fLine1"]=tfLine1;
g_tChLines["fLine2"]=tfLine2;
g_tChLines["pLine1"]=tpLine1;
g_tChLines["pLine2"]=tpLine2;
--если метка перемещалась или индикатор строится впервые рассчитываем линии и выводим их
if boolIndChange then
--для каждой свечи в интервале между метками получить максимальное и минимальное
--значение цены
--сравниваем время меток для задания переменной цикла
--если GETLABLEPOSIXTIME вернула ошибку
if GETLABLEPOSIXTIME (LblId1)==0 or LblId1==0 then
--считываем старое время из массива
posixLblTime1 = tposixOldLabelTime.fplace
--иначе считываем новое время метки
else posixLblTime1 = GETLABLEPOSIXTIME (LblId1)
end
--так же и для второй метки
if GETLABLEPOSIXTIME (LblId2)==0 or LblId2==0 then
posixLblTime2 = tposixOldLabelTime.splace
else posixLblTime2 = GETLABLEPOSIXTIME (LblId2)
end
--получаем значения индекса свечи по его posix-времени
CndlIdx1=tposixByTime[posixLblTime1];
CndlIdx2=tposixByTime[posixLblTime2];
--если метка перемещена вправо за последнюю свечу, то индекс = максимальному
if CndlIdx1 == nil then CndlIdx1 = Size()-5 end
if CndlIdx2 == nil then CndlIdx2 = Size()-4 end
--находим более раннюю свечу
if CndlIdx1 < CndlIdx2 then
j=CndlIdx1;
k=CndlIdx2
else
j=CndlIdx2;
k=CndlIdx1
end
--для всех свечей внутри диапазона меток
for i = j, k, 1 do
--находим максимальное и минимальное значение и индекс свечки
h = t[i].high;
l = t[i].low;
if h~=0 then
if h >= TrndH then
TrndH = h;
tABIdx["hi"] = i--индекс свечки
end;
end
if l~=0 then
if TrndL==0 then TrndL = l end;
if l <= TrndL then
TrndL = l;
tABIdx["lo"] = i--индекс свечки
end;
end
end
--находим количество свечек на интервале тренда (от точек А и В)
IntervalCndlNmbr = tABIdx["hi"] - tABIdx["lo"];
--если получили отрицательное число(слева индекс максимума, тренд вниз), то инвертируем
if IntervalCndlNmbr < 0 then
TrUp=false;
TrDn=true;
APointIdx=tABIdx["hi"];
BPointIdx=tABIdx["lo"];
APointLvl=TrndH;
BPointLvl=TrndL;
else
TrUp=true;
TrDn=false;
APointIdx=tABIdx["lo"];
BPointIdx=tABIdx["hi"];
APointLvl=TrndL;
BPointLvl=TrndH;
IntervalCndlNmbr=-IntervalCndlNmbr
end;
--вычисляем коэффициент наклона прямой
--отрицательный (тренд вниз),положительный (тренд вверх)
koef = (APointLvl - BPointLvl)/IntervalCndlNmbr
--цикл для вычисления значений всеx линий
j=0;
for i=APointIdx, BPointIdx, 1 do
--вычисляем значения точек основного тренда
--i-индекс свечи, j - номер шага
tChTrend[i] = Round.math_round(APointLvl+koef*j,g_PriceScale);
--заносим значения тренда в глобальную таблицу
g_tChLines.tChTrend = tChTrend[i]
--вычисляем значения точек верхней и нижней границы канала
h = t[i].high;
l = t[i].low;
if h - tChTrend[i] > 0 and h~=0 then
if
ChUpMax < h - tChTrend[i]
then
--максимальное отклонение от тренда вверх
ChUpMax = h - tChTrend[i];
--индекс свечи с максимальным отклонением от тренда
idxUpMax = i;
end
end
if tChTrend[i] -l > 0 and l~=0 then
if
ChDnMin < tChTrend[i] -l
then
ChDnMin = tChTrend[i] - l;
idxDnMin = i;
end
end
j=j+1;
end
--количество шагов от точки А
StepsUp=Round.math_round(ChUpMax/koef,0)
--сдвиг назад для тренда вверх, сдвиг вперед для тренда вниз
AidxUp = APointIdx - StepsUp;
BidxUp = BPointIdx - StepsUp;
--количество шагов от точки А
StepsDn=Round.math_round(ChDnMin/koef,0)
--сдвиг назад для тренда вверх, сдвиг вперед для тренда вниз
AidxDn = APointIdx + StepsDn;
BidxDn = BPointIdx + StepsDn;
--цикл по сдвинутому назад диапазону
j=0;
for i=AidxUp, BidxUp, 1 do
--линия тренда верхней границы канала
tChUp[i] = math_round(APointLvl+koef*j,g_PriceScale);
g_tChLines.tChUp = tChUp[i]
if idx==Size() then
message("PUTINDICATOR_Up "..tostring(g_tChLines.tChUp).." "..tostring(i))
end
j=j+1;
end
--цикл по сдвинутому вперед диапазону
j=0;
for i=AidxDn, BidxDn, 1 do
--линия тренда нижней границы канала
tChDn[i] = math_round(APointLvl+koef*j,g_PriceScale);
g_tChLines.tChDn = tChDn[i]
--if idx==Size() then
--message("PUTINDICATOR_Dn "..tostring(g_tChLines.tChDn).." "..tostring(i))
--end
j=j+1;
end
--вычисляем ExtLine
--koef положительный
if TrUp==true then
--линия тренда верхней границы канала
--ниже уровня точки А
j=0;
for i=AidxUp, 2*AidxUp-BidxDn, -1 do
tChUp[i] = math_round(APointLvl+koef*j,g_PriceScale);
g_tChLines.tChUp = tChUp[i]
j=j-1;
end
--выше уровня точки А
j=0;
for i=AidxUp, BidxDn, 1 do
tChUp[i] = math_round(APointLvl+koef*j,g_PriceScale);
g_tChLines.tChUp = tChUp[i]
if i==BPointIdx then
ExtLine1Level=tChUp[i]
local ExtLine1idx=i
end
if i==BidxDn then
ExtLine2Level=tChUp[i]
local ExtLine2idx=i
end
j=j+1;
end
--линия медианы
j=0;
--ниже уровня точки А
for i=APointIdx, AidxUp, -1 do
tChTrend[i] = Round.math_round(APointLvl+koef*j,g_PriceScale);
g_tChLines.tChTrend = tChTrend[i]
if i==AidxUp then
ExtLine6Level=tChTrend[i]
local ExtLine6idx=i
end
j=j-1;
end
j=0;
--выше уровня точки B
for i=BPointIdx, BidxDn, 1 do
tChTrend[i] = Round.math_round(BPointLvl+koef*j,g_PriceScale);
g_tChLines.tChTrend = tChTrend[i]
if i==BidxDn then
ExtLine3Level=tChTrend[i]
local ExtLine3idx=i
end
j=j+1;
end
--линия тренда нижней границы канала
j=0;
--ниже уровня точки А
for i=AidxDn, AidxUp, -1 do
tChDn[i] = math_round(APointLvl+koef*j,g_PriceScale);
g_tChLines.tChDn = tChDn[i]
if i==APointIdx then
ExtLine4Level=tChDn[i]
local ExtLine4idx=i
end
if i==AidxUp then
ExtLine5Level=tChDn[i]
local ExtLine5idx=i
end
j=j-1;
end
end
--koef отрицательный
if TrDn==true then
--линия тренда нижней границы канала
--от уровня точки B и ниже
j=0;
for i=BidxDn, BidxUp, 1 do
tChDn[i] = math_round(BPointLvl+koef*j,g_PriceScale);
g_tChLines.tChDn = tChDn[i]
if i==BPointIdx then
ExtLine1Level=tChDn[i]
local ExtLine1idx=i
end
if i==BidxUp then
ExtLine2Level=tChDn[i]
local ExtLine2idx=i
end
j=j+1;
end
--линия медианы
--от уровня выше точки А до точки А
j=0;
for i=APointIdx, AidxDn, -1 do
tChTrend[i] = Round.math_round(APointLvl+koef*j,g_PriceScale);
g_tChLines.tChTrend = tChTrend[i]
if i==AidxDn then
ExtLine6Level=tChTrend[i]
local ExtLine6idx=i
end
j=j-1;
end
--ниже точки В
j=0;
for i=BPointIdx, BidxUp, 1 do
tChTrend[i] = Round.math_round(BPointLvl+koef*j,g_PriceScale);
g_tChLines.tChTrend = tChTrend[i]
if i==BidxUp then
ExtLine3Level=tChTrend[i]
local ExtLine3idx=i
end
j=j+1;
end
--линия тренда верхней границы канала
--от уровня выше точки А до точки А
j=0;
for i=AidxUp, AidxDn, -1 do
tChUp[i] = math_round(APointLvl+koef*j,g_PriceScale);
g_tChLines.tChUp = tChUp[i]
if i==APointIdx then
ExtLine4Level=tChUp[i]
local ExtLine4idx=i
end
if i==AidxDn then
ExtLine5Level=tChUp[i]
local ExtLine5idx=i
end
j=j-1;
end
--от уровня ниже точки В
j=0;
for i=BidxUp, 2*BidxUp-AidxDn, 1 do
tChUp[i] = math_round(APointLvl+koef*j,g_PriceScale);
g_tChLines.tChUp = tChUp[i]
j=j+1;
end
end
if TrUp==true then
--уровни IntLine
IntLine1=tChUp[APointIdx]
IntLine2=tChTrend[AidxDn]
IntLine3=tChUp[AidxDn]
IntLine4=tChTrend[BidxUp]
IntLine5=tChDn[BidxUp]
IntLine6=tChDn[BPointIdx]
end
if TrDn==true then
IntLine1=tChDn[APointIdx]
IntLine2=tChTrend[AidxUp]
IntLine3=tChDn[AidxUp]
IntLine4=tChTrend[BidxDn]
IntLine5=tChUp[BidxDn]
IntLine6=tChUp[BPointIdx]
end
--вычисление значений fLne1 и fLne2
j=0
for i=BPointIdx,Size()-1 do
tfLine1[i] = Round.math_round(BPointLvl-koef*j,g_PriceScale);
tfLine2[i] = Round.math_round(BPointLvl-koef*j/2,g_PriceScale);
g_tChLines.tfLine1 = tfLine1[i]
g_tChLines.tfLine2 = tfLine2[i]
--message("PUTINDICATOR tfLine2_i "..tostring(g_tChLines.tfLine2).." "..tostring(i));
j=j+1
end
--вычисление значений pLine
if TrUp then
--1-ая точка - значение цены - APointLvl, значение времени - APointIdx
--2-ая точка - значение цены - IntLine6, значение времени - BidxDn
--3-я точка - значение цены - IntLine6, значение времени - 2*BidxDn-BPointIdx
p1koef=Round.math_round((IntLine6-APointLvl)/(BidxDn-APointIdx),g_PriceScale)
p2koef=Round.math_round((IntLine6-APointLvl)/(2*BidxDn-BPointIdx-APointIdx),g_PriceScale)
end
if TrDn then
--1-ая точка - значение цены - APointLvl, значение времени - APointIdx
--2-ая точка - значение цены - IntLine6, значение времени - BidxUp
--3-я точка - значение цены - IntLine6, значение времени - 2*BidxUp-BPointIdx
p1koef=Round.math_round((IntLine6-APointLvl)/(BidxUp-APointIdx),g_PriceScale)
p2koef=Round.math_round((IntLine6-APointLvl)/(2*BidxUp-BPointIdx-APointIdx),g_PriceScale)
end
j=0
for i=APointIdx,Size()-1 do
tpLine1[i] = Round.math_round(APointLvl+p1koef*j,g_PriceScale);
g_tChLines.tpLine1 = tpLine1[i]
tpLine2[i] = Round.math_round(APointLvl+p2koef*j,g_PriceScale);
g_tChLines.tpLine2 = tpLine2[i]
j=j+1
end
g_APointIdx=APointIdx;
g_BPointIdx=BPointIdx;
g_APointLvl=APointLvl;
g_BPointLvl=BPointLvl;
ChTrnd=GETTRENDLINE(1,g_APointIdx,g_BPointIdx,"ChTrend")
if TrUp then
Aidx=AidxUp
Bidx=BidxDn
end
if TrDn then
Aidx=AidxDn
Bidx=BidxUp
end
ChTrndExt=GETTRENDLINE(25,Aidx,Bidx,"ChTrend")
ChUp=GETTRENDLINE(2,AidxUp,BidxUp,"ChUp")
ChUpExt=GETTRENDLINE(26,Aidx,Bidx,"ChUp")
ChDn=GETTRENDLINE(3,AidxDn,BidxDn,"ChDn")
ChDnExt=GETTRENDLINE(27,Aidx,Bidx,"ChDn")
if TrUp then
Aidx=AidxUp
Bidx=BidxUp
end
if TrDn then
Aidx=AidxDn
Bidx=BidxDn
end
APntLvl=GETHORLINE(g_APointLvl,4,Aidx)
BPntLvl=GETHORLINE(g_BPointLvl,5,Bidx)
IntLin1=GETHORLINE(IntLine1,6,g_APointIdx)
if TrUp then Lu=AidxDn end
if TrDn then Lu=AidxUp end
IntLin2=GETHORLINE(IntLine2,7,Lu)
IntLin3=GETHORLINE(IntLine3,8,Lu)
if TrUp then Lu=BidxUp end
if TrDn then Lu=BidxDn end
IntLin4=GETHORLINE(IntLine4,9,Lu)
IntLin5=GETHORLINE(IntLine5,10,Lu)
IntLin6=GETHORLINE(IntLine6,11,g_BPointIdx)
fLne1=GETFLINE(12,g_BPointIdx,"fLine1")
fLne2=GETFLINE(13,g_BPointIdx,"fLine2")
if TrUp then
Aidx=AidxUp
Bidx=BidxDn
ActionIdx=2*Bidx-Aidx
end
if TrDn then
Aidx=AidxDn
Bidx=BidxUp
ActionIdx=2*Bidx-Aidx
end
APntTme=GETVERTLINE(Aidx,14,g_APointLvl)
pLne1=GETTRENDLINE(15,APointIdx,Size()-1,"pLine1")
pLne2=GETTRENDLINE(16,APointIdx,Size()-1,"pLine2")
BPntTme=GETVERTLINE(Bidx,17,g_BPointLvl)
ActionZone=GETVERTLINE(ActionIdx,18,g_BPointLvl)
Lu=BPointIdx
ExtLine1=GETHORLINE(ExtLine1Level,19,Lu)
if TrUp then
Lu=BidxDn
end
if TrDn then
Lu=BidxUp
end
ExtLine2=GETHORLINE(ExtLine2Level,20,Lu)
ExtLine3=GETHORLINE(ExtLine3Level,21,Lu)
Lu=APointIdx
ExtLine4=GETHORLINE(ExtLine4Level,22,Lu)
if TrUp then
Lu=AidxUp
end
if TrDn then
Lu=AidxDn
end
ExtLine5=GETHORLINE(ExtLine5Level,23,Lu)
ExtLne6=GETHORLINE(ExtLine6Level,24,Lu)
--перестроили индикатор-устанавливаем флаг
flagIndExist=true;
flagLblModify=false
end
return ChTrnd,ChUp,ChDn,APntLvl,BPntLvl,IntLin1,IntLin2,IntLin3,IntLin4,IntLin5,IntLin6,fLne1,fLne2,APntTme,pLne1,pLne2,BPntTme,ExtLine1,ExtLine2,ExtLine3,ExtLine4,ExtLine5,ExtLne6,ChTrndExt,ChUpExt,ChDnExt
end
function math_round (num, idp)
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
function GETHORLINE(Level,LineNumber,Luch)
--Luch - индекс свечи от которой начнется прямая
local indx
local Line
local z
indx=Size()
for i=0,indx do
if Luch==nil then
Line=Level
else
if i<=Luch then
Line=nil
else
Line=Level
end
end
z=SetValue(i, LineNumber, Line)
--if Level==ExtLine5Level then
--message("GETHORLINE_z "..tostring(z))
--end
end
return Line
end
function GETTRENDLINE(LineNumber,APntIdx,BPntIdx,Trend)
---[[
local Line
local indx
local TrLine={}
indx=Size()-1;
for i=0,indx do
if i < APntIdx then
TrLine[i]=nil
SetValue(i+1, LineNumber, TrLine[i])
end
if i > BPntIdx then
TrLine[i]=nil
SetValue(i+1, LineNumber, TrLine[i])
end
if i>=APntIdx and i<=BPntIdx then
TrLine[i]=g_tChLines[Trend][i]
if LineNumber==2 then
message("GETTRENDLINE "..tostring( g_tChLines[Trend][i]).." "..tostring(i))
end
SetValue(i+1, LineNumber, TrLine[i])
end
end
return TrLine
--]]
end
function GETFLINE(LineNumber,BPntIdx,Trend)
---[[
local Line
local indx
local TrLine={}
--message("GETTRENDLINE LineNumber Trend "..tostring(LineNumber).." "..tostring(Trend));
SetValue(1, LineNumber, nil)
indx=Size();
--message("GETFLINE BPntIdx "..tostring(BPntIdx));
for i=1,indx do
if i < BPntIdx then
TrLine[i]=nil
SetValue(i+1, LineNumber, TrLine[i])
end
if i >= BPntIdx then
TrLine[i]=g_tChLines[Trend][i]
SetValue(i+1, LineNumber, TrLine[i])
--message("GETFLINE BPntIdx "..tostring(TrLine[i]));
end
end
return TrLine
--]]
end
function GETVERTLINE(PointIndex,LineNumber,PointValue)
local value
for i=0,Size()-1 do
if i<=PointIndex then
value=nil
SetValue(i, LineNumber, value)
end
if i==PointIndex+1 then
value=PointValue
SetValue(i, LineNumber, value)
end
if i>PointIndex+1 then
value=nil
SetValue(i, LineNumber, value)
end
end
return value
end
function OnDestroy ()
local tmp
tmp=DelAllLabels(Settings.AssetID)
end
Format={}
function Format.FTEXT (V)
--функция подставляет нули при их отсутствии на первой позиции даты-времени
V=tostring (V)
if string.len (V) == 1 then V = "0".. V end
return V
end
return Format
Round={}
function Round.math_round (num, idp)
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
return Round
|