VPM, думаете я что-то понял из ваших слов? Покумекал и вопрос решил методом от противного, Если на основе проблемного кода индикатора для Quik нейросеть написала беспроблемный код для ТрейдингВью, то почему бы не поступить наоборот? Я так и сделал, на основании беспроблемного кода для TradingView нейросеть написала мне беспроблемный код для Quik, теперь все работает без ошибок.
Привет всем! Реализовал код индикатора. Это осциллятор двигающийся в диапазоне от 100 до -100. Возникла проблема с неадекватным поведением индикатора на последней свече, при получении новой информации по ценной бумаге он зашкаливает, то есть упирается в предельный уровень своего движения. При переключении на другую ценную бумагу и возврат обратно индикатор показывает правильное значение до получения новой информации и снова начинает зашкаливать.
Код
-- Глобальная таблица настроек индикатора
Settings = {
Name = "Levels Force Index", -- Название индикатора
Period = 13, -- Период для расчета EMA
Overbought = 60, -- Уровень перекупленности (по умолчанию 60)
Oversold = -60, -- Уровень перепроданности (по умолчанию -60)
line = { -- Настройки линий индикатора
{
Name = "LFI", -- Имя основной линии индикатора
Color = RGB(255, 0, 0), -- Цвет основной линии (красный)
Type = TYPE_LINE, -- Тип линии
Width = 1 -- Толщина линии
},
{
Name = "Level 0", -- Нейтральный уровень
Color = nil, -- Цвет будет задан динамически
Type = TYPE_LINE, -- Тип линии
Width = 1 -- Толщина линии
},
{
Name = "Overbought Level", -- Уровень перекупленности
Color = nil, -- Цвет будет задан динамически
Type = TYPE_LINE, -- Тип линии
Width = 1 -- Толщина линии
},
{
Name = "Oversold Level", -- Уровень перепроданности
Color = nil, -- Цвет будет задан динамически
Type = TYPE_LINE, -- Тип линии
Width = 1 -- Толщина линии
}
},
Overlay = false -- Отображение поверх графика (false - отдельное окно)
}
-- Функция инициализации индикатора
function Init()
-- Динамически назначаем цвет всех уровней
local mainLineColor = Settings.line[1].Color -- Цвет основной линии
Settings.line[2].Color = mainLineColor -- Цвет нейтрального уровня
Settings.line[3].Color = mainLineColor -- Цвет уровня перекупленности
Settings.line[4].Color = mainLineColor -- Цвет уровня перепроданности
return #Settings.line -- Возвращаем количество линий индикатора
end
-- Переменные для хранения состояния индикатора
local EMA_Up = nil -- EMA положительных изменений
local EMA_Down = nil -- EMA отрицательных изменений
local alpha = nil -- Коэффициент сглаживания для EMA
-- Основная функция расчета индикатора
function OnCalculate(index)
-- Получаем текущую цену закрытия и объем
local Close = C(index)
local Volume = V(index)
-- Если это первый период, инициализируем переменные
if index == 1 then
EMA_Up = 0
EMA_Down = 0
alpha = 2 / (Settings.Period + 1) -- Вычисляем коэффициент сглаживания
return 0, 0, Settings.Overbought, Settings.Oversold -- Возвращаем значения для уровней
end
-- Рассчитываем изменение цены
local DeltaP = Close - C(index - 1)
-- Определяем Up и Down с учетом объема
local Up = DeltaP > 0 and DeltaP * Volume or 0
local Down = DeltaP < 0 and math.abs(DeltaP) * Volume or 0
-- Рассчитываем EMA_Up и EMA_Down
if index > 1 then
EMA_Up = alpha * Up + (1 - alpha) * EMA_Up
EMA_Down = alpha * Down + (1 - alpha) * EMA_Down
end
-- Рассчитываем значение Levels Force Index (LFI)
local LFI
if (EMA_Up + EMA_Down) ~= 0 then
LFI = ((EMA_Up - EMA_Down) / (EMA_Up + EMA_Down)) * 100
else
LFI = 0
end
-- Возвращаем значения для всех линий: LFI, уровень 0, уровень перекупленности, уровень перепроданности
return LFI, 0, Settings.Overbought, Settings.Oversold
end
Вопрос в том адекватно ли ведет себя индикатор иcходя из формулы и особенностей Quik? Я так же реализовал данный индикатор для платформы TradingView и там такой проблемы нет.
Я решил проблему в Quik путем добавления буферизации, и теперь индикатор отрисовывается на свече только после ее полного закрытия. но это не то чтобы мне хотелось. Возможно ли решить проблему без буферизации?
Код
-- Глобальная таблица настроек индикатора
Settings = {
Name = "Levels Force Index", -- Название индикатора
Period = 13, -- Период для расчета EMA
Overbought = 60, -- Уровень перекупленности (по умолчанию 60)
Oversold = -60, -- Уровень перепроданности (по умолчанию -60)
line = { -- Настройки линий индикатора
{
Name = "LFI", -- Имя основной линии индикатора
Color = RGB(255, 0, 0), -- Цвет основной линии (красный)
Type = TYPE_LINE, -- Тип линии
Width = 1 -- Толщина линии
},
{
Name = "Level 0", -- Нейтральный уровень
Color = nil, -- Цвет будет задан динамически
Type = TYPE_LINE, -- Тип линии
Width = 1 -- Толщина линии
},
{
Name = "Overbought Level", -- Уровень перекупленности
Color = nil, -- Цвет будет задан динамически
Type = TYPE_LINE, -- Тип линии
Width = 1 -- Толщина линии
},
{
Name = "Oversold Level", -- Уровень перепроданности
Color = nil, -- Цвет будет задан динамически
Type = TYPE_LINE, -- Тип линии
Width = 1 -- Толщина линии
}
},
Overlay = false -- Отображение поверх графика (false - отдельное окно)
}
-- Функция инициализации индикатора
function Init()
-- Динамически назначаем цвет всех уровней
local mainLineColor = Settings.line[1].Color -- Цвет основной линии
Settings.line[2].Color = mainLineColor -- Цвет нейтрального уровня
Settings.line[3].Color = mainLineColor -- Цвет уровня перекупленности
Settings.line[4].Color = mainLineColor -- Цвет уровня перепроданности
return #Settings.line -- Возвращаем количество линий индикатора
end
-- Переменные для хранения состояния индикатора
local EMA_Up = nil -- EMA положительных изменений
local EMA_Down = nil -- EMA отрицательных изменений
local alpha = nil -- Коэффициент сглаживания для EMA
local LastBarIndex = nil -- Индекс последнего завершенного бара
-- Основная функция расчета индикатора
function OnCalculate(index)
-- Получаем текущую цену закрытия и объем
local Close = C(index)
local Volume = V(index)
-- Проверяем, является ли текущий бар завершенным
if index == Size() then
-- Если это последний бар, используем данные только если бар завершился
if LastBarIndex == index then
-- Бар уже обработан, возвращаем предыдущее значение
return LFI, 0, Settings.Overbought, Settings.Oversold
else
-- Запоминаем индекс нового бара
LastBarIndex = index
end
end
-- Если это первый период, инициализируем переменные
if index == 1 then
EMA_Up = 0
EMA_Down = 0
alpha = 2 / (Settings.Period + 1) -- Вычисляем коэффициент сглаживания
return 0, 0, Settings.Overbought, Settings.Oversold -- Возвращаем значения для уровней
end
-- Рассчитываем изменение цены
local DeltaP = Close - C(index - 1)
-- Определяем Up и Down с учетом объема
local Up = DeltaP > 0 and DeltaP * Volume or 0
local Down = DeltaP < 0 and math.abs(DeltaP) * Volume or 0
-- Рассчитываем EMA_Up и EMA_Down
if index > 1 then
EMA_Up = alpha * Up + (1 - alpha) * EMA_Up
EMA_Down = alpha * Down + (1 - alpha) * EMA_Down
end
-- Рассчитываем значение Levels Force Index (LFI)
local LFI
if (EMA_Up + EMA_Down) ~= 0 then
LFI = ((EMA_Up - EMA_Down) / (EMA_Up + EMA_Down)) * 100
else
LFI = 0
end
-- Возвращаем значения для всех линий: LFI, уровень 0, уровень перекупленности, уровень перепроданности
return LFI, 0, Settings.Overbought, Settings.Oversold
end
Я не программист и для написания кода пользовался одной из нейросетей. Буду благодарен за помощь в решении проблемы в виде исправленного кода.