Товарищи не понимаю в чем проблема, так как в компиляторе* с тестовыми параметрами (заданными вручную) все работает и тикеры акции есть и параметр CCI на против каждой акции есть, а при запуске скрипта в QUIK выдает ошибку: 27: bad 'for' limit (number expected, got nil). Устранить не получается. Добавил даже при nil выводить другое значение, не помогло. Помогите пожалуйста добрые люди.
В компиляторе выдает так, но там заданы параметры (данные) в ручную.
Код:
-- Настройки
local CCI_PERIOD = 20 -- Период для расчета CCI
local OVERBOUGHT = 200 -- Уровень перекупленности
local OVERSOLD = -200 -- Уровень перепроданности
local UPDATE_INTERVAL = 600 * 1000 -- Интервал обновления в миллисекундах (10 минут)
-- Создаем таблицу для вывода результатов
local results_table = AllocTable() -- Создаем таблицу
AddColumn(results_table, 1, "Тикер", true, QTABLE_STRING_TYPE, 10) -- Колонка для тикера
AddColumn(results_table, 2, "CCI", true, QTABLE_DOUBLE_TYPE, 10) -- Колонка для значения CCI
CreateWindow(results_table) -- Создаем окно таблицы
SetWindowPos(results_table, 100, 100, 400, 300) -- Позиция и размер окна
-- Функция для расчета CCI
function CalculateCCI(ticker, period)
-- Получаем исторические данные (Дневной таймфрейм)
local highs = {}
local lows = {}
local closes = {}
-- Используем getCandles для получения данных
local size = getNumCandles(ticker, INTERVAL_D1, 0, period)
if size == 0 then
return nil -- Если данные отсутствуют, возвращаем nil
end
for i = 1, size do
local candle = getCandle(ticker, INTERVAL_D1, i - 1)
highs[i] = candle.high
lows[i] = candle.low
closes[i] = candle.close
end
-- Рассчитываем типичную цену
local typical_price = {}
for i = 1, period do
typical_price[i] = (highs[i] + lows[i] + closes[i]) / 3
end
-- Рассчитываем SMA типичной цены
local sma = 0
for i = 1, period do
sma = sma + typical_price[i]
end
sma = sma / period
-- Рассчитываем среднее отклонение
local mean_deviation = 0
for i = 1, period do
mean_deviation = mean_deviation + math.abs(typical_price[i] - sma)
end
mean_deviation = mean_deviation / period
-- Рассчитываем CCI
local cci = (typical_price[period] - sma) / (0.015 * mean_deviation)
return cci
end
-- Основная функция скринера
function ScanStocks()
Clear(results_table) -- Очищаем таблицу перед новым сканированием
-- Получаем список всех акций
local stocks = getClassSecurities("TQBR") -- Класс акций на MOEX
if not stocks then
message("Не удалось получить список акций.")
return
end
-- Проходим по всем акциям
for i = 1, #stocks do
local ticker = stocks[i]
local cci = CalculateCCI(ticker, CCI_PERIOD) -- Рассчитываем CCI
if cci then -- Проверяем, что CCI рассчитан
-- Добавляем данные в таблицу
local row = InsertRow(results_table, -1)
SetCell(results_table, row, 1, ticker) -- Тикер
SetCell(results_table, row, 2, string.format("%.2f", cci)) -- Значение CCI
end
end
-- Устанавливаем таймер для следующего вызова через 10 минут
SetTimer(function()
ScanStocks() -- Вызываем функцию сканирования снова
end, UPDATE_INTERVAL)
end
-- Запуск скринера
function OnStop()
ScanStocks() -- Вызываем функцию сканирования
end
-- Запуск скринера при старте
OnStop()
В компиляторе выдает так, но там заданы параметры (данные) в ручную.
Тикер | CCI |
---|---|
SBER | 45.67 |
GAZP | 120.34 |
LKOH | -80.12 |
-- Настройки
local CCI_PERIOD = 20 -- Период для расчета CCI
local OVERBOUGHT = 200 -- Уровень перекупленности
local OVERSOLD = -200 -- Уровень перепроданности
local UPDATE_INTERVAL = 600 * 1000 -- Интервал обновления в миллисекундах (10 минут)
-- Создаем таблицу для вывода результатов
local results_table = AllocTable() -- Создаем таблицу
AddColumn(results_table, 1, "Тикер", true, QTABLE_STRING_TYPE, 10) -- Колонка для тикера
AddColumn(results_table, 2, "CCI", true, QTABLE_DOUBLE_TYPE, 10) -- Колонка для значения CCI
CreateWindow(results_table) -- Создаем окно таблицы
SetWindowPos(results_table, 100, 100, 400, 300) -- Позиция и размер окна
-- Функция для расчета CCI
function CalculateCCI(ticker, period)
-- Получаем исторические данные (Дневной таймфрейм)
local highs = {}
local lows = {}
local closes = {}
-- Используем getCandles для получения данных
local size = getNumCandles(ticker, INTERVAL_D1, 0, period)
if size == 0 then
return nil -- Если данные отсутствуют, возвращаем nil
end
for i = 1, size do
local candle = getCandle(ticker, INTERVAL_D1, i - 1)
highs[i] = candle.high
lows[i] = candle.low
closes[i] = candle.close
end
-- Рассчитываем типичную цену
local typical_price = {}
for i = 1, period do
typical_price[i] = (highs[i] + lows[i] + closes[i]) / 3
end
-- Рассчитываем SMA типичной цены
local sma = 0
for i = 1, period do
sma = sma + typical_price[i]
end
sma = sma / period
-- Рассчитываем среднее отклонение
local mean_deviation = 0
for i = 1, period do
mean_deviation = mean_deviation + math.abs(typical_price[i] - sma)
end
mean_deviation = mean_deviation / period
-- Рассчитываем CCI
local cci = (typical_price[period] - sma) / (0.015 * mean_deviation)
return cci
end
-- Основная функция скринера
function ScanStocks()
Clear(results_table) -- Очищаем таблицу перед новым сканированием
-- Получаем список всех акций
local stocks = getClassSecurities("TQBR") -- Класс акций на MOEX
if not stocks then
message("Не удалось получить список акций.")
return
end
-- Проходим по всем акциям
for i = 1, #stocks do
local ticker = stocks[i]
local cci = CalculateCCI(ticker, CCI_PERIOD) -- Рассчитываем CCI
if cci then -- Проверяем, что CCI рассчитан
-- Добавляем данные в таблицу
local row = InsertRow(results_table, -1)
SetCell(results_table, row, 1, ticker) -- Тикер
SetCell(results_table, row, 2, string.format("%.2f", cci)) -- Значение CCI
end
end
-- Устанавливаем таймер для следующего вызова через 10 минут
SetTimer(function()
ScanStocks() -- Вызываем функцию сканирования снова
end, UPDATE_INTERVAL)
end
-- Запуск скринера
function OnStop()
ScanStocks() -- Вызываем функцию сканирования
end
-- Запуск скринера при старте
OnStop()