Система принятия решений и/или Нечеткая логика(FuzzyLogic)

Страницы: Пред. 1 ... 7 8 9 10 11
RSS
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
TGB,  Обо всем и по порядку.

1000 раз уже на форуме говорил "Не программист, и знания мои так себе". Это раз!
Форум - это площадка для обсуждений, а не выставления амбиций. Это два!

Теперь что касается последней темы:

 1. Не надо "Кусочничить".  Я тему веду последовательно, и рассуждения читать нужно также.
 2. А Вы то понимаете сами?  Пока не создан подход, то и оптимизировать НЕ ЧЕГО, от слова совсем?
 3. Ответ на Ваш вопрос. Оптимизация - это КОМПРОМИС. Поменяйте понимание и все встанет по местам.
 4. Повторюсь мне  не сложно:
Подход - Инвестиционный (означает тф. месячный и больше, в квик их нет).
Задача - возможность торговать и управлять 1 инструментом так и портфелем (универсальность).
Структура - модульная, много разового использования.
Интерфейс - наипростейший, понятный бабушке!

Про КПД, чего Вы рассуждаете? Все КПД моего старенького направленно на эффективность торговли = увеличению баланса счета. Тем более что подход описан, и можно воспользоваться функциями без корутин.

И последнее, Вы не сомневайтесь, сомнения нужны на стадии анализа, а когда решение принято, нужно действовать. Попробуйте. Ну или обосновано возражайте.
 
Цитата
VPM написал:
Попурри на тему "Три тополя на Плющихи" в исполнении ... .  ::

Зацените на сколько удобен интерфейс конечного пользователя в этом подходе.

Код

Преимущества MARKETDATA_PRO v1.0:

Вы не учитываете тот факт, что только Вы знаете это .
Мне как пользователю непонятно  зачем мне это.
--------------------------
Слишком.сложно, много букв. Трудно выявлять ошибки.
--------------------
Попробуйте не дублировать уже описанное.
--------------------
Все общее разместите в начале. Например так:
Код
-- Примеры использования универсальной системы: 
market  =   "TQBR"    
ticker  =   "SBER"  
 -- Глобальный экземпляр 
MDP  =  MarketData_Pro.Manager:new()

 -- 1. УНИВЕРСАЛЬНЫЙ ТЕХНИЧЕСКИЙ АНАЛИЗ ДЛЯ ЛЮБЫХ ДАННЫХ 

 -- Анализ цены последней сделки 
 local  price_analysis  =  MDP:getOrCreate{ interval  =  INTERVAL_H1,   param  =   "last" }
 print ( "Цена SMA20:" , price_analysis:sma( 20 ))
 print ( "Цена RSI14:" , price_analysis:rsi( 14 ))

 -- Анализ стакана (биды) 
 local  bid_analysis  =  MDP:getOrCreate{    interval  =  INTERVAL_M5,  param  =   "bid" }
 print ( "Биды EMA10:" , bid_analysis:ema( 10 ))
 print ( "Биды STDDEV20:" , bid_analysis:getIndicator( "STDDEV" ,  20 ))

 -- Анализ объема 
 local  volume_analysis  =  MDP:getOrCreate{  interval  =  INTERVAL_M15,  param  =   "volume" }
 print ( "Объем SMA30:" , volume_analysis:sma( 30 ))

 -- 2. КАСТОМНЫЕ ИНДИКАТОРЫ ДЛЯ ЛЮБЫХ ПАРАМЕТРОВ 

 -- Регистрация индикатора для спреда 
MDP:registerIndicator( "SPREAD_EMA" ,  function (buffer, period)
     if  buffer.size  <  period  then   return   nil   end 
     local  sum  =   0 
     for  i  =   1 , period  do  sum  =  sum  +  buffer:last(i).value   end 
     return  round(sum / period,  4 )
 end ,  "EMA for Spread" , {"numeric"})

 -- Анализ спреда bid/offer 
 local  spread_data  =  MDP:getOrCreate{    description  =   "Bid-Offer Spread" }
 -- Здесь можно обновлять буфер вручную с вычисленным спредом 
spread_data:updateBuffer( "value" ,  0.15 )  -- пример спреда 

 print ( "Спред EMA10:" , spread_data:getIndicator( "SPREAD_EMA" ,  10 ))

 -- 3. УНИВЕРСАЛЬНЫЙ АНАЛИЗ РАЗНЫХ ТИПОВ ДАННЫХ 

 local  analyses  =  {
    {param  =   "last" , desc  =   "Price Analysis" },
    {param  =   "bid" , desc  =   "Bid Analysis" }, 
    {param  =   "volume" , desc  =   "Volume Analysis" },
    {param  =   "value" , desc  =   "Value Analysis" }
}

 for  _, analysis  in  ipairs(analyses)  do 
     local  data  =  MDP:getOrCreate{ ticker  =   "GAZP" , interval  =  INTERVAL_D1, param  =  analysis.param  }
     local  sma  =  dat a:sma( 20 )
     local  rsi  =  dat a:rsi( 14 )
    print ( string.format ( "%s - SMA20: %.2f, RSI14: %.1f" ,  analysis.desc, sma  or   0 , rsi  or   0 ))
 end 

 -- 4. COMPLEX MULTI-PARAMETER ANALYSIS 

 interval  =  INTERVAL_H1

 -- Анализ нескольких параметров одновременно 
 local  multi_analysis  =   function ()
     local  price  =  MDP:getOrCreate{  param  =   "last"   }
     local  volume  =  MDP:getOrCreate{ param  =   "volume"      }
     local  bids  =  MDP:getOrCreate{ param  =   "bid"     }
     local  price_trend  =  price:ema( 10 )  >  price:ema( 20 )
     local  volume_spike  =  volume:sma( 5 )  >  volume:sma( 20 )  *   1.5 
     local  bid_strength  =  bids:ema( 5 )  >  bids:ema( 10 )  
     return  price_trend  and  volume_spike  and  bid_strength
 end 

 -- 5. DYNAMIC INDICATOR CREATION 

 -- Создание индикатора на лету 
 local  dynamic_indicator  =   function ()
    MDP:registerIndicator( "VOLUME_PRICE_RATIO" ,  function (buffer, priceBuffer, period)
         if   not  priceBuffer  or  buffer.size  <  period  then   return   nil   end 
        
         local  volume_avg  =   0 
         local  price_avg  =   0 
        
         for  i  =   1 , period  do 
             local  vol_item  =  buffer:last(i)
             local  price_item  =  priceBuffer:last(i)
             if  vol_item  and  price_item  then 
                volume_avg  =  volume_avg  +  vol_item.value
                price_avg  =  price_avg  +  price_item.value
             end 
         end 
        
        volume_avg  =  volume_avg / period
        price_avg  =  price_avg / period
        
         return  volume_avg /  math.max (price_avg,  0.001 )
     end ,  "Volume-Price Ratio" , {"volume"})
 end 

Универсальная система - это такая система, разработчик которой не имеет представления где и как ее будут применять.
-----------------------
Пользователь такой системы не в состоянии понять все, что включил в нее разработчик.
-------------------------
В результате реально либо используется 10 процентов  возможности такой системы, либо пользователь начинает делать свою - не универсальную.
 
nikolz,  На счет сложности, для меня очень сложно, здесь с Вами не поспоришь. Отсюда бывает и путаница.

Не могу согласиться: "Универсальная система - это такая система, разработчик которой не имеет представления где и как ее будут применять.".  На  все известно и источники и методы, а использование их на прямую зависит от сложности самой торговой системы. Изначально думал для удобства сделать единый интерфейс рыночных данных, как то само собой добавились индикаторы и вся остальная инфраструктура и все вылилось в целый фреймворк.   Конечно нужно тестирование и оптимизация.

"Пользователь такой системы не в состоянии понять все, что включил в нее разработчик." Так ведь и задача стоит, не нужно пользователю начинка, подключил блок и пользуйся понятным простым интерфейсом. Меня "ушатала" постоянная переделка. Задача все таки, удобство получать в торговых подходах, а не упражнения в программировании.  Удобно и то что есть алгоритмы которые использует большинство, ATR, StDev, средниеи.
 
"Едем дальше, видим больше"! На мой взгляд данный подход, нужно распространить на получение "Серверных данных". Для понимания проблематики, архитектуру предлагается использовать общею для фондового и сросного рынков?  Задача все та же.

Задача - возможность торговать и управлять 1 инструментом так и портфелем (универсальность), с учетом рисков (как квиковских, так и собственно ручных), ну и конечно одной из основных задач управление позицией.
Структура - модульная, много разового использования.
Интерфейс - наипростейший, понятный бабушке!

Обобщенно свести квиковские в функции в удобную оболочку:

Функции взаимодействия скрипта Lua и Рабочего места QUIK

  • getDepoEx - функция для получения позиций по инструментам указанного типа
  • getMoneyEx - функция для получения информации по денежным позициям указанного типа
  • getFuturesLimit - функция для получения информации по фьючерсным лимитам
  • getFuturesHolding - функция для получения информации по фьючерсным позициям
  • getSecurityInfo - функция для получения информации по инструменту?
  • getTradeDate - функция для получения даты торговой сессии
  • CalcBuySell - функция для расчета максимально возможного количества лотов в заявке? (скорее для контроля, уж больно тяжелая?)
  • getPortfolioInfoEx - функция для получения значений параметров таблицы «Клиентский портфель» с учетом срока расчётов
  • getBuySellInfoEx - функция для получения параметров (включая срок расчётов) таблицы «Купить/Продать» (Важная для маржинальной торговли!)
 
Вариант реализации подхода, что скажите?
Код
QuickDataManager = {}
QuickDataManager.__index = QuickDataManager

-- Конструктор класса
function QuickDataManager:new(firmid, client_code)
    local obj = setmetatable({}, self)
    obj.firmid = firmid
    obj.client_code = client_code
    obj.data = {}  -- Для хранения кэшированных данных
    obj.loaded = {}  -- Для отслеживания загруженных параметров
    return obj
end

-- Функция для ленивой загрузки данных с учетом firmid и client_code
function QuickDataManager:_loadData(param, optional_params)
    -- Формируем уникальный ключ для кэширования (с учетом параметров)
    local cache_key = param .. "_" .. (optional_params or "")
    
    if self.loaded[cache_key] then
        return self.data[cache_key]  -- Возвращаем из кэша
    end

    -- Если данных нет в кэше, загружаем их
    local data
    if param == "money" then
        -- Вызов getMoneyEx для получения информации по деньгам
        data = getMoneyEx(self.firmid, self.client_code, optional_params.tag or "", optional_params.currcode or "", optional_params.limit_kind or 0)
    elseif param == "depo" then
        -- Вызов getDepoEx для получения позиций по инструментам
        data = getDepoEx(self.firmid, self.client_code, optional_params.sec_code or "", optional_params.trdaccid or "", optional_params.limit_kind or 0)
    elseif param == "portfolio" then
        -- Вызов getPortfolioInfoEx для получения информации по клиентскому портфелю
        data = getPortfolioInfoEx(self.firmid, self.client_code, optional_params.limit_kind or 0, optional_params.board_tag or "", optional_params.currency or "")
    elseif param == "buy_sell" then
        -- Вызов getBuySellInfoEx для получения параметров по заявкам
        data = getBuySellInfoEx(self.firmid, self.client_code, optional_params.class_code or "", optional_params.sec_code or "", optional_params.price or 0)
    elseif param == "futures_limit" then
        -- Вызов getFuturesLimit для получения фьючерсных лимитов
        data = getFuturesLimit(self.firmid, optional_params.trdaccid or "", optional_params.limit_type or 0, optional_params.currcode or "")
    elseif param == "futures_holding" then
        -- Вызов getFuturesHolding для получения позиций по фьючерсным счетам
        data = getFuturesHolding(self.firmid, optional_params.trdaccid or "", optional_params.sec_code or "", optional_params.type or 0)
    end
    
    -- Кэшируем загруженные данные
    self.data[cache_key] = data
    self.loaded[cache_key] = true

    return data or {}
end

-- Доступ к данным с ленивой загрузкой
function QuickDataManager:__index(key)
    if key == "money" then
        return self:_loadData("money", {tag = "default", currcode = "USD", limit_kind = 0})
    elseif key == "depo" then
        return self:_loadData("depo", {sec_code = "SBER", trdaccid = "1234", limit_kind = 0})
    elseif key == "portfolio" then
        return self:_loadData("portfolio", {limit_kind = 0, board_tag = "TQBR", currency = "RUB"})
    elseif key == "buy_sell" then
        return self:_loadData("buy_sell", {class_code = "TQBR", sec_code = "SBER", price = 1000})
    elseif key == "futures_limit" then
        return self:_loadData("futures_limit", {trdaccid = "TQBR", limit_type = 0, currcode = "USD"})
    elseif key == "futures_holding" then
        return self:_loadData("futures_holding", {trdaccid = "1234", sec_code = "SBER", type = 0})
    else
        -- Загружать другие параметры по необходимости
        return self:_loadData(key)
    end
end

-- Пример использования
local manager = QuickDataManager:new("Firm1", "Client1")

-- Ленивое обращение к данным
local money = manager.money  -- Получение информации по деньгам
local depo = manager.depo    -- Получение позиций по инструментам
local portfolio = manager.portfolio  -- Получение информации по портфелю
local buy_sell = manager.buy_sell  -- Получение информации по заявкам на покупку/продажу
 
Что делает:

QuickDataManager:new(firmid, client_code). Конструктор создаёт экземпляр менеджера с обязательными параметрами firmid и client_code.
Это основные параметры для работы с системой QUIK. Все остальные параметры передаются как опциональные в виде таблицы в функции.

QuickDataManager:_loadData(param, optional_params). Это основная функция для ленивой загрузки данных. В зависимости от параметра (например, "money", "depo", "portfolio", и т.д.), она делает запросы к соответствующим функциям QUIK. Функция также проверяет, есть ли уже кэшированные данные для этого параметра, и если они есть — возвращает их. Если данных нет, выполняется запрос и кэшируются результаты? Здесь основной вопрос как правильно организовать работу?

QuickDataManager:__index(key). Метатаблица __index отвечает за доступ к данным через ключи, такие как money, depo, portfolio и другие. Для каждого ключа вызывается соответствующая функция ленивой загрузки, которая получает необходимые данные и кэширует их.

Параметры (например, tag, currcode, limit_kind, sec_code и другие) передаются через опциональные параметры, что позволяет адаптировать запросы под различные нужды и сохранить гибкость подхода.

Пример использования. При первом обращении к данным (manager.money, manager.depo, manager.portfolio, и т.д.) данные будут загружены, затем они будут кэшироваться для последующего использования без лишних запросов к системе. Что позволяет уменьшить нагрузку на систему и ускорить последующие операции. Как альтернатива. Если нужно избежать повторного получения одинаковых данных, можно добавить механизм для "очистки" кэша по истечении времени или по запросу.
 
Цитата
VPM написал:
Что делает:

QuickDataManager:new(firmid, client_code).  Конструктор создаёт экземпляр менеджера с обязательными параметрами firmid и client_code.
Это основные параметры для работы с системой QUIK. Все остальные параметры передаются как опциональные в виде таблицы в функции.

QuickDataManager:_loadData(param, optional_params). Это основная функция для ленивой загрузки данных. В зависимости от параметра (например, "money", "depo", "portfolio", и т.д.), она делает запросы к соответствующим функциям QUIK. Функция также проверяет, есть ли уже кэширов анные данные для этого параметра, и если они есть — возвращает их. Если данных нет, выполняется запрос и кэшируются результаты? Здесь основной вопрос как правильно организовать работу?

QuickDataManager:__index(key).  Метатаблица __index отвечает за доступ к данным через ключи, такие как money, depo, portfolio и другие. Для каждого ключа вызывается соответствующая функция ленивой загрузки, которая получает необходимые данные и кэширует их.

Параметры (например, tag, currcode, limit_kind, sec_code и другие) передаются через опциональные параметры, что позволяет адаптировать запросы под различные нужды и сохранить гибкость подхода.

Пример использования. При первом обращении к данным (manager.money, manager.depo, manager.portfolio, и т.д.) данные будут загружены, затем они будут кэшироваться для последующего использования без лишних запросов к системе. Что позволяет уменьшить нагрузку на систему и ускорить последующие операции. Как альтернатива. Если нужно избежать повторного получения одинаковых данных, можно добавить механизм для "очистки" кэша по истечении времени или по запросу.
Лучше не заставлять пользователя изучать Lua и не вводить без острой надобности специальные термены.
Например,
вместо:
Код
QuickDataManager:new(firmid, client_code). 
написал бы
Код
fimid=XXXX
client_code=EEEE
а в скрипте под капотом написал бы
Код
QuickDataManager:new(firmid, client_code). 
про термины:
"ленивая" загрузка  - пользователю обязательно это знать? Тогда что такое ленивая и какие еще есть ?
----------------------------
Т е сначала решите, для кого Вы пишите эту инструкцию. Т е какой у него уровень знаний должен быть, чтобы понять, что вы написали.
 
и еще
В своем скрипте все параметры типа firmid, client  получаю из QUIK.
Т е их не надо вводить пользователю.
 
nikolz,  Это не инструкция, это описные одного из вариантов подхода, если хотите мое виденье, выложено на обсуждение сообществу.  

"ленивая" загрузка - описание есть выше, такую возможность предоставляет ООП, если не очень понятно можно посмотреть фреймворк на который  я ссылаюсь.

Подход уже тоже устарел так как нашлись более удобные решения, например кэширует результаты и имеет авто обновление через корутину (с ограничением нагрузки),
 
Цитата
nikolz написал:
В своем скрипте все параметры типа firmid, client  получаю из QUIK. Т е их не надо вводить пользователю.
Не очень понимаю этот подход, ну если с firmid все еще понятно, зависит в чей терминал скипт загружен. То с client не все очевидно, все равно приходится в водить,  
 
Цитата
VPM написал:
Цитата
nikolz написал:
В своем скрипте все параметры типа firmid, client  получаю из QUIK. Т е их не надо вводить пользователю.
Не очень понимаю этот подход, ну если с firmid все еще понятно, зависит в чей терминал скипт загружен. То с client не все очевидно, все равно приходится в водить,  
можете вводить это не принципиально.
Для информации.
Вот что надо ввести пользователю в мой скрипт
Код
clas_list="QJSIM:0,SPBFUT:1,CETS:2"; --список классов счетов и тип инструментов 0 -акции 1-фьючерсы 2- валюта 3- опционы
sec_list="ROSN,GAZP,SBER,PLZL,GMKN,CHMF,HYDR,LKOH,MOEX,SNGS"  --список инструментов для портфеля, если нет, то все инструменты по заданным классам
task_list="task1,task2,task3,task4"  -- список существующих задач
sec_user={ --параметры устанавливаемые пользователем для инструментов по умолчанию
1, --интервал свечей
0, --подписка на стакан
0, --флаг разрешения коротких позиций
0,--флаг разрешения установки стопа  1 -обычный, 2-скользящий, 3 -take 4-stop и take
"task1",
"task2" --список задач по умолчанию для каждого инструмента
}
т е
clas_list - список торгуемых классов
sec_list -список торгуемых инструментов
task_list -- список существующих задач, которые ему дает разработчик или он пишет сам  
sec_user -- параметры для все инструментов
----------------------
Для каждого инструмента,задачи можно  через ':' указать индивидуальные параметры.
Пользователю не надо изучать луа, если он не хочет писать задачи.
===================
У меня тоже универсальная система.  
 
Код
    if self.loaded[cache_key] then
        return self.data[cache_key]  -- Возвращаем из кэша
    end

Т.к. я вижу в данных таблицы, которые постоянно изменяются, то не очень понятно о каком кеше идет речь. Кеш нужен для условно постоянно информации, а не для той, что изменяется каждую секунду.
Эти данные нужны для совершения торговых операций, например, проверить, что там с доступными средствами. Обращаться постоянно к ним особой нужды нет.
Также есть данные изменяемые при изменении статуса сессии, завершении клиринга - вот их можно помещать в кеш, и обновлять оный по этим событиям.

И да, делать для этого объекты - так себе затея.

Входящие параметры для скрипта - это код инструмента, торговый счет, субсчет (код клиента) если их несколько. Все. Остальное получается из терминала. Впрочем даже счет и субсчет можно подставить из данных для класса инструмента. Зачастую они и нужны.

Если Вы пишите скрипты для себя, то, конечно, делайте как хотите. Но если уже для других, то всегда отталкивайтесь, что максимум что может сделать пользователь - это изменить файл настроек, где все максимально просто и понятно. Не надо искать информацию в служебных окнах терминала. Либо делать интерфейс, через который тоже просто задаются параметры.
 
Цитата
VPM написал:
"Едем дальше, видим больше"! На мой взгляд данный подход, нужно распространить на получение "Серверных данных". Для понимания проблематики, архитектуру предлагается использовать общею для фондового и сросного рынков?  Задача все та же.

Задача - возможность торговать и управлять 1 инструментом так и портфелем (универсальность), с учетом рисков (как квиковских, так и собственно ручных), ну и конечно одной из основных задач управление позицией.
Структура - модульная, много разового использования.
Интерфейс - наипростейший, понятный бабушке!

Обобщенно свести квиковские в функции в удобную оболочку:

Функции взаимодействия скрипта Lua и Рабочего места QUIK  
getDepoEx - функция для получения позиций по инструментам указанного типа
 getMoneyEx - функция для получения информации по денежным позициям указанного типа
 getFuturesLimit - функция для получения информации по фьючерсным лимитам
 getFuturesHolding - функция для получения информации по фьючерсным позициям
 getSecurityInfo - функция для получения информации по инструменту?
 getTradeDate - функция для получения даты торговой сессии
 CalcBuySell - функция для расчета максимально возможного количества лотов в заявке? (скорее для контроля, уж больно тяжелая?)
 getPortfolioInfoEx - функция для получения значений параметров таблицы «Клиентский портфель» с учетом срока расчётов
 getBuySellInfoEx - функция для получения параметров (включая срок расчётов) таблицы «Купить/Продать» (Важная для маржинальной торговли!)
У меня эти функции спрятаны.
Пользователю доступ к ним не нужен и он про них ничего не знает и знать не хочет.
В задаче он просто читает нужную переменную скрипта.  
 
У меня данные обновляются лишь по колбекам.
Поэтому нет смысла их кэшировать.
 
VPM,
Возможно Вы не обратили внимание,
но у меня
ВСЯ УНИВЕРСАЛЬНАЯ СИСТЕМА это 380 операторов
из них 120 - это конечный автомат обработки колбеков
и 60 - конечный автомат обработки задач.
-----------------------------
+ скрипты задач.  
которые могут создать событие на выставление удаление перестановку заявок.
----------------------
Интерфейс к ней показал ранее.
 
сделал новый интерфейс еще проще:
Код
list={
--список инструментов для портфеля, если нет, то все инструменты по заданным классам
sec="ROSN,GAZP,SBER,PLZL,GMKN,CHMF,HYDR,LKOH,MOEX,SNGS"  
task="task1,task2,task3,task4"  -- список существующих задач
}
user_sec="   interval:1,quote:0,short:0,stop:0,takeprofit:0,task:task1:task2,quota:0"

--user_sec--параметры пользователя для sec  по умолчанию--interval --интервал свечей
--quote --подписка на стакан
--short -- разрешениe коротких позиций
--stop--флаг разрешения установки стопа  1 -обычный, 2-скользящий,
--takeprofit, -- флаг разрешения TakePrifit
--task---список задач по умолчанию для каждого инструмента
--quota--для средств для покупки в одной заявке
--можно задавать индивидуальные параметры для задач и инструментов
 
поправил комментарии
Код
list={
--список инструментов для портфеля
sec="ROSN,GAZP,SBER,PLZL,GMKN,CHMF,HYDR,LKOH,MOEX,SNGS"  
task="task1,task2,task3,task4"  -- список существующих задач
}
user_sec="   interval:1,quote:0,short:0,stop:0,takeprofit:0,task:task1:task2,quota:0"

Страницы: Пред. 1 ... 7 8 9 10 11
Читают тему
Наверх