Модуль подключения индикаторов папки LuaIndicators с сайта ARQA (https://arqatech.com/ru/support/files/)

Страницы: 1
RSS
Модуль подключения индикаторов папки LuaIndicators с сайта ARQA (https://arqatech.com/ru/support/files/)
 
1. Инструкция приведена в комментариях теста модуля.

2.  Код теста:
Код
--                                Инструкция
-- 1. Скачать папку LuaIndicators (Примеры функций расчета индикаторов терминала QUIK на языке Lua) с сайта
-- https://arqatech.com/ru/support/files/  и переслать в папку расположения info.exe.
-- 2. Модуль подключения индикаторов(под именем mod_IND.lua) переслать в папку расположения info.exe.
-- 3. Запустить тест test_IND.
-- ----
-- P.S.
-- 1. Учитывать, что при расчете индикаторов первые значения (1 .... Период расчета индикатора - 1)
-- обычно nil.
-- 2. Результат расчета индикатора может иметь несколько значений и это определяется функцией OnCalculate 
-- кода используемого индикатора папки LuaIndicators.
-- 3. В модуле mod_IND.lua представлены три примера объявления заголовочных функций описаний параметров 
-- подключаемых индикаторов. Параметры такой функции это список полей из таблицы Settings соответствующего 
-- индикатора папки LuaIndicators, для которых требуется задать значения, определяющие поведение создаваемого
-- замыкания.

---------------------------------------------------------------------
timeout = 300
is_run = true

function main()
   -- GetDataSource подключается к графику --
   local function GetDataSource(class_code, sec_code, timeframe)
      local ds, Error = CreateDataSource(class_code, sec_code, timeframe)
      -- Ждет 10 сек., пока данные будут получены с сервера --
      for i = 1, 1000 do if not ((Error == "" or Error == nil) and ds:Size() == 0) then break end; sleep(10) end
      if Error ~= "" and Error ~= nil then
         message(debug.getinfo(1).currentline..': Ошибка подключения к графику: '..Error)
         return nil
      end
      return ds
   end
   -------------------------------- Тест индикаторов -------------------------------------------------
   local INDICATORS = require('mod_IND')
   ---------------------------------------------------------------------------------------------------
   --  Подключение к источнику данных (графику)
   local DS = GetDataSource(getClassInfo('QJSIM') and 'QJSIM' or 'TQBR', 'SBER', INTERVAL_M1)
   if not DS then return end -- не удалось подключиться к источнику данных ---
   local size = DS:Size()
   message('size = ' .. size)
   -------------------------------------------------------------------------------------------------
   --   <Функция создания индикаторов> (<Параметры индикатора>)
   -- Результат: функция-замыкание расчета индикатора.
   ------
   -- Вызов полученного замыкания:
   --     <Функция-замыкание>(<Очередное значение для расчета индикатора>)
   --  Результат (возможно несколько значений, определяемых видом индикатора):  значения индикатора, 
   -- определяемые параметрами создания замыкания на основе кода индикатора в папке ...Lua\\LuaIndicators.
   -- !! В кодах индикаторов результат определяется функцией OnCalculate.
   ---------
   --   !  Для сброса индикатора-замыкания в начальное состояние, его надо пересоздать.
   ---------------------------------------------------------------------------------------------------
   local AC_IND1 = INDICATORS.AC(
      3,     -- Период короткой скользящей
      5,     -- Период длинной скользящей
      'SMA'  -- Метод расчета скользящих (SMA, MMA, EMA, WMA, SMMA, VMA)
   ) 

   local AC_IND2 = INDICATORS.AC( -- return value
      5,     -- Период короткой скользящей
      9,     -- Период длинной скользящей
      'SMA'  -- Метод расчета скользящих (SMA, MMA, EMA, WMA, SMMA, VMA)
   ) 

   local MA_IND1 = INDICATORS.MA( -- return value
      5,     -- Период скользящей
      'SMA'  -- Метод расчета скользящих (SMA, MMA, EMA, WMA, SMMA, VMA)
   )

   local MA_IND2 = INDICATORS.ADX( -- return {['ADX'], ['+DI'], ['-DI']}
      7,       -- Период короткой скользящей
      'EMA'    -- Метод расчета скользящих (SMA, MMA, EMA, WMA, SMMA, VMA)
   )
   
   -- Использование индикатора --- 
   for i = 1, size do 
      AC_IND1(DS:C(i))
   end

   for i = 1, size > 15 and 15 or size do 
      AC_IND2(DS:C(i))
   end

   for i = 1, size > 15 and 15 or size  do 
      local tbl = {MA_IND1(DS:C(i))}
      message('MA_IND1 : ' .. tostring(tbl[2]))
   end

   for i = 1, size > 100 and 100 or size  do
     MA_IND2(DS:H(i))
   end
   ---- Сброс индикатора (запрос нового замыкания) ---
   MA_IND2 = INDICATORS.MA( -- return value
      100,       -- Период  скользящей
      'EMA'    -- Метод расчета скользящих (SMA, MMA, EMA, WMA, SMMA, VMA)
   )
   -- Тест индикаторов Конец  ----------------------------------------

   while is_run do
      sleep(timeout)
   end
end

function OnStop()
   is_run = false
   return 10000  -- (млс.) ожидание завершения потока main прежде чем принудительное его завершение ---
end


------------------------------------------------------------------------------------------------
2.  Код модуля:
Код
--- Модуль подключения индикаторов папки LuaIndicators с сайта ARQA (https://arqatech.com/ru/support/files/):
-- Примеры функций расчета индикаторов терминала QUIK на языке Lua.
-------------------------------------------- 
local IND = {}
---------------------------------------------------------------------------------------------------
--- КОНСТАНТЫ -------------------------------------------------------------------------------------
local SMA,MMA,EMA,WMA,SMMA,VMA = 'SMA','MMA','EMA','WMA','SMMA','VMA'
local OPEN,HIGH,LOW,CLOSE,VOLUME,MEDIAN,TYPICAL,WEIGHTED,DIFFERENCE,ANY = 'O','H','L','C','V','M','T','W','D','A'
---------------------------------------------------------------------------------------------------
---------------- Подключение к роботу индикаторы из папки LuaIndicators (с файлами кодов индикаторов) ------------
local pach_IND = getWorkingFolder() .. '\\LuaIndicators'  --     Путь к кодам индикаторов --
-- ! Код индикатора из папки LuaIndicators помещаются в исходном виде внутрь оболочки-фабрики (на Lua), 
-- обеспечивающей создание индикаторов-замыканий с параметрами заданными при вызове такой фабрики.
--  ! Пролог: начало функции-фабрики:     ------
local Prologue = [[ -- создание окружения фабрики ---
local PRM = {...}  ---
PRM = PRM[1]       -- Таблица параметров индикатора ---
------------------------------------------------------
-- Таблица окружения создаваемого замыкания индикатора --
-- Начальная инициализация тиблицы-окружения замыканий-индикаторо (объектами, используемыми в вычислении индикаторов)
-- выполняется из ! текущего окружения фабрики. Существенно только то, что эти объекты должны существовать. 
local ENV_IND = {  
   -- Объекты из _ENV, необходимые для расчета индикаторов --
   tonumber = tonumber
   , tostring = tostring
   , type = type
   , select = select
   , table = table
   , pack = pack or table.pack        -- 
   , unpack = unpack or table.unpack  --
   , string = string
   , math = math
   , package = package
   , require = require
   , debug = debug
   , next = next
   , os = os
   , io = io
   , RGB = RGB
   , message = message
   , getWorkingFolder = getWorkingFolder
   , getScriptPath = getScriptPath
   -- !! Переменнпой ENV_begin таблиц-окружения замыканий-индикаторов будет присвоено окружение-родитель (с чего все началось)
   , ENV_begin = type(ENV_begin) == 'table' and ENV_begin or _ENV  --  при первом формировании таблицы-окружения ENV_begin = _ENV
}
local ENV_ENV = _ENV   -- Сохранения окружения --
_ENV = ENV_IND   -- Переключение окружения перед инициализацией замыкания индикатора ---
]] 

-- -- ! Эпилог: в конце функции-фабрики:     ------
local Epilogue = [[
---- Начало эпилога ---
   if not PRM then
      message(debug.getinfo(1).currentline .. ' ! ОШИБКА: не заданы параметры индикатора ' .. tostring(Settings.Name), 3)
      return 
   end
   --- 
   for k, v in next, PRM do  -- присвоение параметров индикатора --
      if not Settings[k] then
         -- #### Выдача сообщения об ошибки ---
         message(debug.getinfo(1).currentline .. ' ! ОШИБКА в параметрах индикатора ' .. tostring(Settings.Name), 3)
      end
      Settings[k] = v 
   end
   Init()  -- Инициализация фабрики параметрами индикатора --- 

   -- Перегрузка function GetValueEX ---
   function GetValueEX(I,VT, DS) 
      return ds_IND
   end
   
   -- Перегрузка function CandleExist(I,ds)   -- проверка существования свечи  ---
   function CandleExist(I,ds)
      return true
   end 
   
   local Index_IND = 0   -- Внутренний счетчик обращения к индикатору (внешняя локальная переменная замыкания)---
   ------
   _ENV = ENV_ENV    -- Восстановление окружения ---
   return            -- возврат замыкания расчета очередного значения шндикатора --
      function (DS)  -- функция-замыкание для вычисления индикатора --
         _ENV = ENV_IND  -- ENV_IND - переменная хранения окружения, созданного для замыкания индикатора
         ds_IND = DS     -- Передача значения в расчет индикатора ----
         Index_IND = Index_IND + 1
         return  OnCalculate(Index_IND)
      end
]]

local Indicator_factories = {}   -- таблица функций-фабрик создания индикаторов {<Имя индикатора> = <Функция>}  --
----
-- Функция создает фабрики индикаторов на основе кодов из папки LuaIndicators  --
-- Результат функция-замыкание индикатора: F_IND ---
--   Вызов функции: F_IND(val)
-- где val - очередное значение источника индикатора --
-- а результат функции: значения индикатора (их может быть несколько, в зависимости от вида индикатора)
local function Get_Indicator(Indic, Settings)
   local func = Indicator_factories[Indic]
   if not func then -- Ищется код индикатора и создается его фабрика ---
      -- Создание фабрики индикатора (поиск кода индикатора, добавление пролога и эпилога, 
      -- компиляция и добавление в Indicator_factories)
      local folder_of = pach_IND .. '\\' .. Indic .. '.lua'   
      local kod_IND
      --- Чтениие источника  ---
      local kodZ, io_open, err =  pcall( io.open, folder_of, 'r')  
      if io_open then
         kod_IND = io_open:read('*a')
         assert(io_open:close())
      else
         message(debug.getinfo(1).currentline .. ' ! ОШИБКА: нет кода индикатора ' .. tostring(Indic), 3)
         return
      end 
      
      kodZ, func, err =  pcall(load, Prologue .. kod_IND .. Epilogue)
      if not func then
         message(debug.getinfo(1).currentline .. ' ! ОШИБКА: трансляции код индикатора ' .. tostring(Indic) .. '. Подробности: ' .. tostring(err), 3)
         return
      end
      ---
      Indicator_factories[Indic] = func  -- 
   end
   -- Возвращает экземпляр функции индикатора с состоянием, определяемым параметрами вызова данной функции ---
   return func(Settings)   -- результат функция-замыкание индикатора ---
end

---------------------------------------------------------------------------------------------------
--   <Функция создания индикаторов> (<Параметры индикатора>)
-- Результат: функция-замыкание расчета индикатора.
------
-- Вызов полученного замыкания:
--     <Функция-замыкание>(<Очередное значение для расчета индикатора>)
--  Результат (возможно несколько значений, определяемых видом индикатора):  значения индикатора, 
-- определяемые параметрами создания замыкания на основе кода индикатора в папке ...Lua\\LuaIndicators.
-- !! В кодах индикаторов результат определяется функцией OnCalculate.
-----
--   !  Для сброса индикатора-замыкания в начальное состояние, его надо пересоздать.
---------------------------------------------------------------------------------------------------
--------------- Далее представлены три примера объявления заголовочных функций описаний параметров 
-- подключаемых индикаторов. Параметры такой функции это список полей из таблицы Settings соответствующего 
-- индикатора папки LuaIndicators, для которых требуется задать значения, определяющие поведение создаваемого
-- замыкания. Результат: значения функции OnCalculate (их может быть несколько) оответствующего индикатора.
-- AC (Accelerator/Decelerator Oscillator)
IND.AC = function(
   SHORT_Period,  -- Период короткой скользящей
   LONG_Period,   -- Период длинной скользящей
   Metod          -- Метод расчета скользящих (SMA, MMA, EMA, WMA, SMMA, VMA)
)
   local Settings = {
      SHORT_Period = SHORT_Period, 
      LONG_Period = LONG_Period, 
      Metod = Metod
   }
   
   -- Возвращает экземпляр функции индикатора с состоянием, определяемым параметрами вызова текущей функции--
   return Get_Indicator('AC', Settings)
end

--Average Directional Movement Index ("ADX")
IND.ADX = function( 
   Period,        -- Период
   Metod          -- Метод расчета скользящих (SMA, MMA, EMA, WMA, SMMA, VMA)
)
   local Settings = {
      Period = Period, 
      Metod = Metod
   }
   
   -- Возвращает экземпляр функции индикатора с состоянием, определяемым параметрами вызова текущей функции-
   return Get_Indicator('ADX', Settings)
end

--Moving Average ("MA")    ( 50000 циклов,  Period = 100, Metod = SMA:  340 млс.)
IND.MA = function(
   Period,        -- Период
   Metod          -- Метод расчета скользящих (SMA, MMA, EMA, WMA, SMMA, VMA)
)
   local Settings = {
      Period = Period,  
      Metod = Metod
   }
   
   -- Возвращает экземпляр функции индикатора с состоянием, определяемым параметрами вызова текущей функции-
   return Get_Indicator('MA', Settings)
end
--   И так далее (по образу и подобию уже представленных)  ---
return IND
 
На всякий случай:
   в кодах индикаторов папки LuaIndicators используется вызов стандартной функции unpack, который, в версиях Lua 5.3 - 5.4 ошибочен и должно быть: table.unpack(......).
   В коде модуля mod_IND.lua это учитывается как ошибочный вариант так и исправленный (строка в модуле: , unpack = unpack or table.unpack).
 
Интересно: нет ни вопросов, ни замечаний. То ли все ясно, то ли не понятно ничего.
 
Цитата
TGB написал:
Интересно: нет ни вопросов, ни замечаний. То ли все ясно, то ли не понятно ничего.
Скорее не понятно, зачем? Ведь таблица луа это уже модуль. Ну к примеру моя любая программа сейчас выглядит так,
и это не все классы.
При этом память на один инструмент не более 1000 кб, быстродействие алгоритма ограничиваю чтобы не перегружать процессор. Но это только мое мнение.
Код
-- Установите путь к вашему каталогу с модулями
   local path = '...\\modules';
    package.path = path.."\\?.lua;".. package.path
   
    -- Проверка и подключение необходимых модулей
    local function safeRequire(moduleName)
        local success, result = pcall(require, moduleName)
        if not success then
          error("Failed to load module: " .. moduleName .. "\n" .. result)
        end
        return result
    end
    
    -- Модули
    --local Log = require("LogClass")
    
    local Utility = require("Utility")
    
    local Queue = require("QueueClass") -- Реализация класса `Queue` двусвязной очереди
    local Color = require("ColorClass")
    local Label = require("LabelClass")
    local WindowCoordinates = require("WindowCoordinatesClass")
    local TableSaverLoader = require("TableSaverLoader")
    
    local TimeHandler = require("TimesClass")
    local Checker = require("Checker") --setmetatable(Checker, __object_behaviour)
    local Event = require("EventClass")
    --local VersionManager = require("VersionManager")
    local StateMachine = require("StateMachine") --  Управляет состояниями и переходами между ними.
    local StateManager = require("StateManager") -- Отвечает за сохранение и загрузку состояния из файла.
     
    local DS = require("DSClass") --setmetatable(DS, __object_behaviour)
    local RiskManagement = require("rmClass") --setmetatable(rm, __object_behaviour)
    local MoneyManagement = require("mmClass") --setmetatable(mm, __object_behaviour)
    local CapitalManagement = require("cmClass") --setmetatable(CapitalManagement, __object_behaviour)
 
Цитата
VPM написал:
Скорее не понятно, зачем?
  То есть, если вам в скрипте надо использовать уже существующий индикатор, то вам интересно его программировать  и отлаживать. Если это так, то ваша позиция понятна. Действительно, нет проблем реализовать самому любой индикатор. Но вопрос зачем, когда есть готовые коды некоторых индикаторов?
   Интересно. зачем вы к своему сообщению "присобачили" код? Вы, что, хотите им кого-то напугать  :smile: ?
 
TGB,  Код я скинул и указал параметры для того чтоб показать как реализуются модули, и только.
Цитата
TGB написал:
То есть, если вам в скрипте надо использовать уже существующий индикатор, то вам интересно его программировать  и отлаживать.
Да нет просто скопировать и вставить.
Цитата
TGB написал:
Действительно, нет проблем реализовать самому любой индикатор. Но вопрос зачем, когда есть готовые коды некоторых индикаторов?
Очень редко применяю готовый код, скорее в тестерах для проверки идеи. А вот хорошую идею это да.

Основная проблема этих старых алгоритмов - это их математика, которая плохо подходит для внутри дневной торговли.  
 
Цитата
VPM написал:
Да нет просто скопировать и вставить.
  А это уже интересно. Покажите какой нибуть просто скопированный, вставленный (без последующей модификации) и работающий индикатор из папки LuaIndicators.
 
TGB,  Вся библиотека индикаторов от любезно предоставленная разработчиками копируется и вставляется в папку LuaIndicators. Что тут можно показать? :shock:

Я про другое, это луа, здесь создается таблица и вне вставляются элементы (пусть даже алгоритмы), и затем возвращаем и читаем все ТОЧКА. Для каких целей Ваш алгоритм не очень понятно?
 
Цитата
VPM написал:
Вся библиотека индикаторов от любезно предоставленная разработчиками копируется и вставляется в папку LuaIndicators. Что тут можно показать?
 Вы ускользаете от вопроса. Покажите как вы используете эти индикаторы в своем скрипте?
 
TGB,  Ни как не использую, выше привел код подключения модулей, в том числе алгоритмов, которые ныне упаковываю в класс луа. Вот еще из рабочей программы и здесь уже алгоритмы есть индикаторов
Код
 local FractalAnalyzer = require("FractalAnalyzerClass") --setmetatable(FractalAnalyzer, __object_behaviour)
    local BalanceTracker = require("BalanceTrackerClass")
   --local Analytics = require("Analytics")
   --local Strategy = require("Strategy")
    --local Strategy1 = require("Strategy1") --setmetatable(Strategy1, __object_behaviour)
    --local Strategy2 = require("Strategy2") --setmetatable(Strategy2, __object_behaviour)
   local ChannelPDF = require('ChannelPDFQueueClass')
    local DecyclerQueue = require('DecyclerQueueClass')
    local DetrenderQueue = require('DetrenderQueueClass')
   --local HPR = require("hprsClass") setmetatable(HPR, __object_behaviour)
    local HPR = require("HPRsClassv1") --setmetatable(HPR, __object_behaviour)
    local Result = require("ResultClass")
    local Position = require("PositionClass")
    local Instruction = require("InstructionClass")
    local Signal = require("SignalClass")
    local TimeFrameSynchronizer = require("TimeFrameSynchronizer")
    local TradeManager = require("TradeManagerClass")
 
Вот пример создания

-- Инициализация стратегии Decycler
           --settings.dec = {period = 60, depth = 0, wid = 0, sigma = 1}
           decycler[class][symbol][interval] = DecyclerQueue.new( {
                                         period = 120,
                                         depth = 0, wid = 0, sigma = 1,
                                         scale = feed[1].sec_scale,
                                         step = feed[1].sec_price_step
                                         }
                                         , ds[n][i]--dataSource:getDataSource(class, symbol, interval)
                                         , class, symbol, interval
                                       )
 
Так возвращаю результат
local out = decycler[class_names[1]][symbol_names[n]][interval_values[1]]:calculate(I)
 
Цитата
VPM написал:
выше привел код подключения модулей, в том числе алгоритмов, которые ныне упаковываю в класс луа. Вот еще из рабочей программы и здесь уже алгоритмы есть индикаторов
 И где же индикаторы из папки  LuaIndicators? Покажите маленький тест их использования.
 
А понял, если Вы про это, только на график как индикатор и очень осторожно, так ка это путь убить КВИК на повал. Не знаю как последние алгоритмы разработчиков , не пробовал, а первые это транжирство памяти, и помнится Вы мне тоже помогали с этим вопросом разбираться. Из своего опыта нельзя на прямую использовать в алгоритмах эти индикаторы!
 
Цитата
VPM написал:
Из своего опыта нельзя на прямую использовать в алгоритмах эти индикаторы!
    Это вам так кажется. Вы проверили мои коды и нашли ошибки, в том числе транжирство памяти? Если да, то покажите.
 
Ваш код это некий сервис, по подключению алгоритмов (ну по крайней мере я так понял) наверняка он хороший и правильный, вот тока зачем? Какую задачу хотите решить?
Я показал альтернативный подход через класс луа, хотите используете в алгоритмах программ в потоке маин, хотите в виде индикатора квика, все "по образу и подобию", с контролем памяти, и однообразной инициализацией.
 
Цитата
VPM написал:
Какую задачу хотите решить?
     В заголовке ветки написано: подключение в скрипте индикаторов папки LuaIndicators с сайта ARQA
 
Цитата
TGB написал:
Цитата
VPM написал:
Какую задачу хотите решить?
      В заголовке ветки написано: подключение в скрипте индикаторов папки LuaIndicators с сайта ARQA
Но это не задача, это некий сервис. Повторюсь
Цитата
VPM написал:
Не знаю как последние алгоритмы разработчиков , не пробовал, а первые это транжирство памяти, и помнится Вы мне тоже помогали с этим вопросом разбираться. Из своего опыта нельзя на прямую использовать в алгоритмах эти индикаторы!
Страницы: 1
Читают тему
Наверх