Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
17.11.2025 16:37:35
далее создаю файл для сохранения данных текущего дня Для истории есть отдельная сжатая база глубиной 10 лет. Создаю колбек для обработки данных
Код
local fD=pTD..sec.."/"..int.."/current.txt"; --файл данных текущего дня
local fe=io.open(fD,"w");
if ds then ds:SetUpdateCallback(cb_candle(sec,ds,fe)); else ds={} end
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
пардон, не понял сначала . Расскажу как я делаю подписку. Число инструментов не имеет значения. Сейчас в разрабатываемом роботе 10 инструментов. ------------------------ Подписка делается один раз в функции получения параметров инструментов заданных списком в фале ini. вот фрагмент подписки.
Код
local ds,err;
if int>0 then --подписка на свечи
while ds==nil do ds,err=CreateDataSource(clas,sec,int); sleep(1); end
end
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
17.11.2025 10:50:48
, Если скрипт не осилите, то покажите фрагмент кода, как Вы будете обрабатывать свечи отдельного инструмента/
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
17.11.2025 10:44:48
, Если это у Вас универсальная система, то покажите код для произвольного числа инструментов, список которых будет задавать пользователь либо, этот список формирует сам робот исходя из состояния рынка.
Проблема с нажатием правой кнопки
Пользователь
Сообщений: Регистрация: 30.01.2015
17.11.2025 09:43:32
Когда в таблице в скрипте нажимаю правую кнопку мышки, то вылезает окно квика
Если не знаете, то спросите сначала у Алисы. -------------------------- Содержимое ответа
Понятие Scoping (области видимости) в языке программирования Lua определяет, насколько переменная видна остальной части программы. Это понятие относится к глобальным и локальным переменным. Область видимости — это участок кода программы, в пределах которого можно получить доступ к значению, хранящемуся в переменной. Под блоком понимается:
тело управляющей конструкции (if-then, else, for, while, repeat);
тело функции;
фрагмент кода, заключённый в ключевые слова do...end.
проблема с двойным нажатием кнопки
Пользователь
Сообщений: Регистрация: 30.01.2015
17.11.2025 09:21:59
Цитата
Станислав написал: Организовать какой-то адаптер, который будет заниматься подсчетом количества миллисекунд с нажатия и на основе этих данных отправлять сигнал либо об одиночном либо о двойном нажатии.
Спасибо. Решил проблему иначе. Запоминаю код предыдущего нажатия. Обработку одинарного нажатия выполняю по отпусканию клавиши.
проблема с двойным нажатием кнопки
Пользователь
Сообщений: Регистрация: 30.01.2015
16.11.2025 10:40:06
При двойном нажатии кнопки мыши в таблице созданной в скрипте всегда сначала приходит сигнал об одинарном нажатии кнопки.
Как устранить сигнал об одинарном нажатии при двойном нажатии?
Примеры простого торгового робота на Lua и Python от разработчиков QUIK, Примеры простого торгового робота на Lua и Python от разработчиков QUIK
Пользователь
Сообщений: Регистрация: 30.01.2015
14.11.2025 11:19:32
Цитата
Олег Денисов написал: Может есть у кого-нибудь такой "простой работающий робот qlua с выставлением стопа и профита"?
На сколько простой? ------------------------- В интернете можно найти много предложений роботов для QUIK за деньги . Вы удивитесь, но это все "простые" роботы.
Торговый счёт и код клиента
Пользователь
Сообщений: Регистрация: 30.01.2015
13.11.2025 20:42:01
спросите в браузере Яндекса Алису, она все объяснит простым русским языком.
У Вас скрипт работает лишь один раз. В майн надо делать бесконечный цикл. Читайте документацию.
Индекс запсииси в таблице ордеров
Пользователь
Сообщений: Регистрация: 30.01.2015
13.11.2025 12:18:42
Предположу, что так сбрасывают зависшие каналы, когда их много. ------------------- "Хотелось бы услышать начальника транспортного цеха"
Установка отметок на графике через скрипт
Пользователь
Сообщений: Регистрация: 30.01.2015
12.11.2025 20:06:40
Цитата
gngngn написал: Добрый день код который вы скинули кладет терминал
у меня скорей всего что то с самим терминалом, пробивал несколько простых скриптов, метки создаются - message (tostring(label_id_text)) выводи id метки
Чтобы выводились метки надо установить в скрипте интервал равный интервалу на графике. Установлено 5 минут. идентификатор графика установлен t ag = "SBER_ID" версия QUIK 12.8.0.6 сервер тестовый
Метки на графике в скрипте
Пользователь
Сообщений: Регистрация: 30.01.2015
12.11.2025 16:00:39
По просьбе трудящихся.
Код
label_params={["TEXT"]="",["IMAGE_PATH"]="",["ALIGNMENT"]="Left",["YVALUE"]=0,["DATE"]=0,["TIME"]=0,["R"]=255,["G"]=255,["B"]=255,
["TRANSPARENCY"]=0,["TRANSPARENT_BACKGROUND"]=0,["FONT_FACE_NAME"]='Times New Roman',["FONT_HEIGHT"]=10,["HINT"]=""}
function labeldraw(price, YYYYMMDD,HMS,textlabel, texthint)
label_params.TEXT = textlabel;
label_params.DATE = YYYYMMDD;
label_params.TIME =HMS;
label_params.YVALUE = price;
label_params.HINT = texthint;
label_id_text = AddLabel(tag, label_params)
end
function main()
local i=0; local _size=0;
while true do
local size= getNumCandles(tag);
while size>i do
local t, _, _ = getCandlesByIndex(tag, 0, i, 1)
local z=t[0]; local Hi,Li,Ci,Oi=z.high,z.low,z.close,z.open;
i=i+1;
local Ti=ds:T(i)
YYYYMMDD=100*(100*Ti.year+Ti.month)+Ti.day;
HMS=100*(100*Ti.hour+Ti.min)+Ti.sec;
labeldraw(Hi, YYYYMMDD,HMS,"A", "B")
end
sleep(1)
end
end
function OnInit(p) -- инициализация функции main
sec,clas,int="SBER","QJSIM",5;
tag = "SBER_ID"
ds=CreateDataSource ("sec","QJSIM",5)
while ds==nil do ds,err=CreateDataSource(clas,sec,int); sleep(1); end
end
Установка отметок на графике через скрипт
Пользователь
Сообщений: Регистрация: 30.01.2015
12.11.2025 15:56:51
, Вот решение Вашей хотелки - метки в скрипте:
это скрипт:
Код
label_params={["TEXT"]="",["IMAGE_PATH"]="",["ALIGNMENT"]="Left",["YVALUE"]=0,["DATE"]=0,["TIME"]=0,["R"]=255,["G"]=255,["B"]=255,
["TRANSPARENCY"]=0,["TRANSPARENT_BACKGROUND"]=0,["FONT_FACE_NAME"]='Times New Roman',["FONT_HEIGHT"]=10,["HINT"]=""}
function labeldraw(price, YYYYMMDD,HMS,textlabel, texthint)
label_params.TEXT = textlabel;
label_params.DATE = YYYYMMDD;
label_params.TIME =HMS;
label_params.YVALUE = price;
label_params.HINT = texthint;
label_id_text = AddLabel(tag, label_params)
end
function main()
local i=0; local _size=0;
while true do
local size= getNumCandles(tag) message (size)
-- if size>_size then price, _, _ = getCandlesByIndex(tiker_id, 0, size - 1, 1) _size=size; end
while size>i do
local t, _, _ = getCandlesByIndex(tag, 0, i, 1)
local z=t[0]; local Hi,Li,Ci,Oi=z.high,z.low,z.close,z.open;
i=i+1;
local Ti=ds:T(i)
YYYYMMDD=100*(100*Ti.year+Ti.month)+Ti.day;
HMS=100*(100*Ti.hour+Ti.min)+Ti.sec;
labeldraw(Hi, YYYYMMDD,HMS,"A", "B")
end
sleep(1)
end
end
function OnInit(p) -- инициализация функции main
sec,clas,int="SBER","QJSIM",5;
tag = "SBER_ID"
ds=CreateDataSource ("sec","QJSIM",5)
while ds==nil do ds,err=CreateDataSource(clas,sec,int); sleep(1); end
end
Установка отметок на графике через скрипт
Пользователь
Сообщений: Регистрация: 30.01.2015
12.11.2025 14:16:33
Общие сведения
Индикаторы технического анализа представляют собой отдельный класс скриптов, которые удовлетворяют определенным условиям и расположены в папке LuaIndicators в каталоге терминала. Если папка отсутствует в каталоге, необходимо создать ее вручную. Список скриптов не доступен из диалога Сервисы / LUA скрипты....
При добавлении нового индикатора на график плагин qlua сканирует папку LuaIndicators, проверяет файлы с расширением lua и luac (скомпилированные скрипты lua) на соответствие следующим требованиям:
определена функция Init,
определена функция OnCalculate,
определена таблица Lua с именем Settings, в которой есть поле «Name».
Пример минимального корректного кода для индикатора:
Settings={} Settings.Name = "minimal" function Init() return 1 end function OnCalculate(index) return 1 end
Установка отметок на графике через скрипт
Пользователь
Сообщений: Регистрация: 30.01.2015
12.11.2025 14:14:35
Цитата
gngngn написал: день день. Помоги решить вопрос на графике не отображается метка (текст) причем при проверки message (tostring(label_id_text)) сообщение выдает id метки Так же на графике при нажатии правой кнопки при выборе удалить, строка "все метки в диаграмме" становится активной (получается метка на график попадает, но ее не видно) скрипт отображения метки следующий:
function labeldraw(price, textlabel, texthint) label_params = { TEXT = textlabel, ALIGNMENT = "LEFT", DATE = tostring(os.date("%Y%m%d")), TIME = tostring(os.date("%H%M%S")), R = 0, G = 0, B = 0, TRANSPARENCY = 90, FONT_HEIGHT = 10, TRANSPARENT_BACKGROUND = 1, YVALUE = price, HINT = texthint }
text = "ppppp "..price[0].close labeldraw(price[0].close, text, "eeeeee") message (tostring(price[0].close)) message (tostring(label_id_text)) end
Метки выставляются в индикаторе, а вы написали скрипт.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
06.11.2025 18:49:50
поправил комментарии
Код
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"
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
06.11.2025 18:48:51
сделал новый интерфейс еще проще:
Код
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--для средств для покупки в одной заявке --можно задавать индивидуальные параметры для задач и инструментов
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
06.11.2025 18:36:10
, Возможно Вы не обратили внимание, но у меня ВСЯ УНИВЕРСАЛЬНАЯ СИСТЕМА это 380 операторов из них 120 - это конечный автомат обработки колбеков и 60 - конечный автомат обработки задач. ----------------------------- + скрипты задач. которые могут создать событие на выставление удаление перестановку заявок. ---------------------- Интерфейс к ней показал ранее.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
06.11.2025 18:29:11
У меня данные обновляются лишь по колбекам. Поэтому нет смысла их кэшировать.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
06.11.2025 18:27:36
Цитата
VPM написал: "Едем дальше, видим больше"! На мой взгляд данный подход, нужно распространить на получение "Серверных данных". Для понимания проблематики, архитектуру предлагается использовать общею для фондового и сросного рынков? Задача все та же.
Задача - возможность торговать и управлять 1 инструментом так и портфелем (универсальность), с учетом рисков (как квиковских, так и собственно ручных), ну и конечно одной из основных задач управление позицией. Структура - модульная, много разового использования. Интерфейс - наипростейший, понятный бабушке!
Обобщенно свести квиковские в функции в удобную оболочку:
Функции взаимодействия скрипта Lua и Рабочего места QUIK getDepoEx - функция для получения позиций по инструментам указанного типа getMoneyEx - функция для получения информации по денежным позициям указанного типа getFuturesLimit - функция для получения информации по фьючерсным лимитам getFuturesHolding - функция для получения информации по фьючерсным позициям getSecurityInfo - функция для получения информации по инструменту? getTradeDate - функция для получения даты торговой сессии CalcBuySell - функция для расчета максимально возможного количества лотов в заявке? (скорее для контроля, уж больно тяжелая?) getPortfolioInfoEx - функция для получения значений параметров таблицы «Клиентский портфель» с учетом срока расчётов getBuySellInfoEx - функция для получения параметров (включая срок расчётов) таблицы «Купить/Продать» (Важная для маржинальной торговли!)
У меня эти функции спрятаны. Пользователю доступ к ним не нужен и он про них ничего не знает и знать не хочет. В задаче он просто читает нужную переменную скрипта.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
написал: В своем скрипте все параметры типа 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 -- параметры для все инструментов ---------------------- Для каждого инструмента,задачи можно через ':' указать индивидуальные параметры. Пользователю не надо изучать луа, если он не хочет писать задачи. =================== У меня тоже универсальная система.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
06.11.2025 15:12:23
и еще В своем скрипте все параметры типа firmid, client получаю из QUIK. Т е их не надо вводить пользователю.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
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).
про термины: "ленивая" загрузка - пользователю обязательно это знать? Тогда что такое ленивая и какие еще есть ? ---------------------------- Т е сначала решите, для кого Вы пишите эту инструкцию. Т е какой у него уровень знаний должен быть, чтобы понять, что вы написали.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
06.11.2025 10:25:03
Цитата
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 процентов возможности такой системы, либо пользователь начинает делать свою - не универсальную.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
06.11.2025 06:12:12
Цитата
VPM написал: , 1. Вы не отвечаете на заданные Вам вопросы, ну как минимум в общении это не вежливо! , для меня это и не важно. 2. Ну, нужны Вам все эти гигибайты истории, да и храните, я же не против, я привёл паттерн для текущей задачи. 3. Именно так создал, этот подход убираю ошибки для тестирования. 4. С песней в точку что вижу, с чем разбираюсь, про то и пою, 20 раз уже на это отвечал, если есть проблемы с памятью я записывайте, нет мне несложно повторить и 100 раз одно и тоже. 5. И уж пожалуйста, про время не нужно, оно мне интересно в рамках исполнения моих задач, описанных в скрипта. А про оптимизацию в песнях ни слова . Задачей оптимизации, следящий раз, сейчас найти приемлемое решение для задач описанных выше! 6. Возможно у такого специалиста есть рекомендации по задаче? Или " Слов из песни не выбросить "? ::
У Вас много слов в песне, возможно пропустил Ваш вопрос. Если не сложно, то повторите.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
05.11.2025 19:01:01
, Если вы останавливаете корутины, то теряете время на их остановке и запуске. Это дорогая процедура. Но Вам же время не важно.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
05.11.2025 18:54:47
, Не в обиду, но мне Ваши опусы напоминают песню ямщика: -Ямщик - ты о чем поешь? -Так что вижу, так о том и пою.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
05.11.2025 18:51:59
Цитата
VPM написал: Существует несколько подходов к организации данных в QUIK. Нужно выбрать структуру для проекта, который будет включать в себя: а) DataPoller.lua (планировщик опросов в корутинах); б) MarketData (модуль для работы с рыночными данными); с) DataManager (менеджер данных, который объединяет все вместе).
Учитывая, что задача стоит избежать фризов и минимизировать задержки, а также обеспечить актуальность данных , предлагается следующий подход:
DataPoller будет заниматься асинхронным опросом данных (через корутины) и обновлением кэша. MarketData будет предоставлять интерфейс для доступа к данным (через метатаблицы с ленивой загрузкой и кэшированием). DataManager будет управлять созданием и жизненным циклом источников данных, а также взаимодействием между Poller и MarketData.
При этом мы можем использовать комбинацию подхода 3 (ООП-ленивый доступ) и 4 (кэш + корутина). Тогда концепция выглядит следующим образом:
1. DataPoller. Создает и управляет корутинами для периодического обновления данных. Каждый источник данных (например, тикер) регистрируется в планировщике. Планировщик обновляет кэш данных в фоновом режиме.
2. MarketData. Представляет объект-источник данных (например, свечи, стакан, параметры инструмента). При первом обращении к полю, если данных нет в кэше, они запрашиваются синхронно (редкий случай, но как fallback (запасной план) ). Основной доступ к данным идет из кэша, который асинхронно обновляется планировщиком.
3. DataManager. Инициализирует планировщик и создает источники данных. Предоставляет интерфейс для получения источника данных (например, по тикеру и интервалу для свечей). Управляет жизненным циклом данных (создание, удаление, обновление).
Пример последовательности: Пользователь запрашивает у DataManager данные по SBER (например, свечи M1). DataManager создает объект MarketData для SBER M1, если он еще не создан, и регистрирует его в DataPoller. DataPoller начинает периодически (каждые N ms) обновлять данные для SBER M1 (например, запрашивать последние свечи и класть в кэш). Пользователь обращается к объекту MarketData (например, candles:getValue("close", -1)), и получает данные из кэша. Таким образом, мы имеем асинхронное обновление данных и синхронный доступ к ним без блокировок?
Теперь код для каждого модуля. Начнем с DataPoller (адаптируем тот, что уже есть, но упростим и настроим под эту задачу).
DataPoller будет: Принимать задачи (источники данных) с callback для обновления. Запускать корутины, которые периодически вызывают callback и обновляют кэш. MarketData (источник данных) будет: Иметь метод update() (который будет вызываться планировщиком) для обновления своих данных. Иметь кэш для хранения последних данных. Предоставлять методы для доступа к данным (например, getValue). DataManager будет: Хранить все созданные источники данных (например, по ключу market_ticker_interval). Создавать новые источники, если их нет, и регистрировать их в DataPoller.
Вы это сделали или просто рассуждаете? Если сделали то покажите профиль задержек на тестах и оцените сколько инструментов вы сможете обрабатывать. Какие у Вас результаты на истории?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
05.11.2025 18:49:25
Цитата
VPM написал: Еще раз. Идеальный производственный паттерн работы с QUIK: В QUIK нет смысла "стримить" все свечи постоянно — нужно один раз получить исторический буфер и дальше обновлять только последнюю (текущую, незакрытую) через callback/опрос?
Тогда, Алгоритм модуля MarketData_Pro.Poller, который: а) Загружает исторические свечи (100–500 штук) в UniversalBuffer при инициализации. б) Держит кеш последней свечи (текущий бар) отдельно. с) Обновляет кеш по событию или через быстрый опрос QUIK (getParamEx / getCandlesByIndex). д) По таймфрейму??? проверяет закрытие свечи > переносит кеш в буфер и очищает кеш? е) Отдает актуальные данные любому индикатору через getValue() или прямой доступ к буферу?
Вы ошибаетесь. История торгов нужна не для того, чтобы постоянно ее обрабатывать. На истории проверяют идеи торгов. Я на истории обучаю роботов.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
05.11.2025 18:35:42
Т е примерно в 10000 раз меньше, чем у Вас, если Вы поставите sleep на 1 сек
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
написал: Собственно задачей может быть не только функция, выполняемая в main, но и любой процесс или другой поток со своей VMLua или любом другом языке и даже в облаке или у соседа на компе.
Вот этого точно, не обсуждаю. 1 терминал, 1 маин, множество корутин или сейчас рассматриваю как предлагал альтернативу , . Все остальное к программистам системщикам или , ::
Цитата
написал: Свчеи хранятся в сжатом формаье (степень сжатия примерно 7 раз . 10 лет SBER на 1 мин это 2 млн свечей. Сжатый объем 28МБайт.
Но это тоже для Ваших каких то специфических задач. "Дата соурсе" в квик организовано как интерфейс получения данных о свечах, получил к примеру 100 бар в буфер, обработал расчеты допустим индикатора и все. Обновляется буфер согласно тайм фрейма. Текущее (не завершенную свечу) держим в кеш, обновляется оперативно по колбеку.
Я у Вас спрашивал как вы обрабатываете события последовательно перебираете очередь или есть приоритеты, если есть то чем обосновываете
Приоритеты не имеет смысла делать, так как очередь пока короткая. У моего робота реакция на колбек составляет не более 0.1 ms.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
05.11.2025 14:17:56
посмотрел объем сохраненных данных за период 10 лет по 26 инструментам. Всего 603МБ. сжатых 7Z.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
05.11.2025 14:10:07
Цитата
VPM написал: , А можете описать полный алгоритм, и если приоритеты, если есть на чем основываете? Будет интересно, думаю не только мне.
А смысл? Время уйдет много и не факт что это имеет смысл ------------------------- Могу отвечать на конкретные вопросы,
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
05.11.2025 14:07:14
Сделал автомат получения свечей с биржи по списку торгуемых инструментов. Свчеи хранятся в сжатом формаье (степень сжатия примерно 7 раз . 10 лет SBER на 1 мин это 2 млн свечей. Сжатый объем 28МБайт. При считывании автоматом распаковываются. В результате разработку торговой системы можно делать на истории любой глубины на таймах от 1 мин. Текущий торговый день сохраняю из QUIK в несжатом виде. На следующий день данные записываются в архив в сжатом виде с биржи.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
05.11.2025 13:54:22
Цитата
VPM написал: Основной поток main() нельзя блокировать. main() — это кооперативная петля; если вставить бесконечный цикл без sleep, терминал “зависнет”. Лучшее решение на мой не профессиональный взгляд опрос в отдельной корутине. Почему именно корутина? Lua-корутины позволяют “распараллелить” логику. Можно делать yield-циклы с sleep(1000) без потери отзывчивости терминала. Каждая корутина может следить за своим источником данных (деньги, позиции, котировки и т.п.).
Решаю эти проблемы так. ------------------- Если main делать нечего, то ждет события от колбеков. ------------------------------ Колбеки свои события складывают в очередь. ------------------------------ Если очередь не пустая, то main обслуживает очередь. ----------------------------------------- Задачи тоже могут создавать события. ------------------------- Собственно задачей может быть не только функция, выполняемая в main, но и любой процесс или другой поток со своей VMLua или любом другом языке и даже в облаке или у соседа на компе. --------------------------------
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
04.11.2025 15:15:32
Цитата
VPM написал: И так обсудили разные подходы по организации полного жизненного цикла заявки. Каким подходом пользоваться, каждый определяет для себя сам. Это архитектурная дилемма. Так как окончательного мнения у меня не сложилось, буду пользоваться наиболее понятными для меня подходами. Задача все еще прежняя, собрать модульную структуру в которой торговые стратегии работают независимо отдавая приказы на исполнение. И технологическая, все это дело обслуживает.
Таким образом можно выделить 3 главных блока, которые взаимодействуют ка между собой так и с апи квик. А. полный жизненный цикл заявки. Б. полный жизненный цикл сделки. С. полный жизненный цикл money.
Следовательно в блоках можно условно выделить основное взаимодействие, это пары: 1. заявка / сделка = depo; 2. актив depo / актив money, что в свою очередь можно представить как depo + money = capital.
Следовательно, следующая задача, нужно организовать жизненный цикл money.
Уу меня получилась два конечных автомата и менеджер задач. 1) обрабатывает события по OnOrder, OnStopOrder,OnTanseReblay, и все колбеки в которых нет sec_сode. 2) обрабатывает колбеки, в которых есть sec_code, кроме указанных ранее. 3) менеджер задач запускает задачи торгуемых инструментов. 2) и 3) объединены в одну функцию для оптимизации скорости работы и затрат памяти. --------------------- Список существующих задач определяемся в файле init ----------------------------------- Каждая задача записывается в отдельном файле как отдельная функция ------------------------------ Объем скрипта составляет 500 операторов(строк), из который 300 исполняются лишь при старте скрипта.
У Вас ошибка. результат операции логического И (bit.band) не 1 , а 4 , если бит установлен. т е в вызове должно быть
Код
local a = ActiveLimitOrderExists(52.50, 0x4)
--------------------------------
В Lua 5.3 и 5 4 нет надобности в библиотеке bit вместо
Код
bit.band(order.flags, 0x4)
можно записать так:
Код
order.flags&4
Как экономить на интернет трафике в системе Квик
Пользователь
Сообщений: Регистрация: 30.01.2015
04.11.2025 06:21:03
Цитата
Алкотрейдер написал: Здравствуйте, может кто знает и подскажет, есть временное подключение через мобильного оператора связи, как значительно снизить потребляемый трафик программой, в свойствах сети я обнаружил как квик за полчаса 700 мб интернета скушал, уничтожив все запасы мобильного интернета.
Настройте получение данных лишь те инструменты, которые Вы используете в торгах. Не подписывайтесь на ненужные параметры. Не подписывайтесь на обезличенные сделки. Не Используйте умные настройки. Настройки все руками. Не открывайте стаканы инструментов которыми не торгуете. Проверьте число подписанных инструментов и параметров.
остановка скрипта при запуске QUIK
Пользователь
Сообщений: Регистрация: 30.01.2015
04.11.2025 06:15:38
Если Вам надо чтобы скрипт, запущенный в QUIK остановился при новом старте нужно первую строку в колбек OnInit записать так:
Код
function OnInit(path)
if os.clock()<2 then return end
Автозапуск скрипта LUA при старте QUIK
Пользователь
Сообщений: Регистрация: 30.01.2015
04.11.2025 06:09:45
, Чтобы запущенный скрипт не стартовал автоматом надо сделать так: В колбеке onInit первую строку запишите так:
Код
function OnInit(path)
if os.clock()<2 then return end
--....
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
03.11.2025 15:14:07
Замечу, что замыкание можно заменить обычной функцией с передачей ей таблицы с параметрами, которые хранятся в замыкании. Такая реализация проще в понимании и полностью эквивалентна замыканию.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
03.11.2025 14:17:22
Цитата
Nikolay написал: Любая процедура, вызванная из main не блокирует QUIK. Любая. Хоть завернутая в корутину, хоть вызванная напрямую, хоть в замыкании.
Присоединяюсь
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
03.11.2025 14:05:51
Цитата
Nikolay написал: Поэтому если отправили транзакцию на ордер, то результат - это не колбек OnTransReply, а появление записи по этому ордеру в таблице ордеров. Колбек же OnOrder - это уже следствие появления этой записи, а не наоборот.
Вы ошибаетесь, как раз наоборот Сначала будет колбек,OnOrder, а потом появится запись в таблице заявок.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
02.11.2025 17:13:01
Если вынести повторяющуюся часть кода в функции (для чего они и придуманы):
Код
function order(t,Tor,Nor)
local N=Tor[0]; local flags=t.flags local flag=flags&1; local num=t.order_num; local id=t.trans_id;
for i=1,N do
local s=Tor[i]; --s,id,js,num
if s[4]==num or (id~=0 and s[2]==id) then
if flag==0 then -- заявка не активна удаляем из списка активных если она есть в списке
if N>1 then Tor[i]=Tor[N] end Tor[N]=nil; Tor[0]=N-1;
else --заявка активная записываем ее номер
s[4]=num --записываем номер новой заявки по транзакции
if s[3]==0 then s[3]=Nor; Nor=Nor+1 end
end
break;
end -- заявка в списках
end
if flag==1 and id==0 then
N=N+1; Tor[N]={t.sec_code,0,Nor,num}; Nor=Nor+1 Tor[0]=N; --- активная заявка не найдена заявка выставлена не из скрипта создаем ее
end; -- таблица заявок,стоп-заявок инструмента
end
function transOrd(t,Tor)
local id=t.trans_id; local s,js;
for i=1,N do s=Tor[i]; --s,id,js,num
if s[2]==id then js=s[3];
if js==0 then if N>1 then Tor[i]=Tor[N] end Tor[N]=nil; Tor[0]=N-1; return --отменяем выставление
else s[3]=-js; return end -- отменяем удаление
end
end
end
то конечный автомат для этих колбеков будет совсем простой:
Код
elseif m==2 then --onOrder
order(t,Tor,Nor);
elseif m==3 then --onStopOrder
order(t,Tso,Nso);
elseif m==4 then
local x=t.status local msg=t.result_msg;
if Log then Log:write("status="..x..": транзакция "..t_mes[x+1]..">"..msg.."\n"); Log:flush();end
if x==3 or 2>x or x==15 then return end
---удаляем ошибочные транзакции
message("status="..x..": транзакция "..t_mes[x+1]..">"..msg, 3)
transOrd(t,Tor);
transOrd(t,Tso);
Вот и все.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
Пользователь
Сообщений: Регистрация: 30.01.2015
02.11.2025 16:22:42
Цитата
VPM написал: А если жизненный цикл (путь), расписать по шагам в конкретные процедуры (как , ) подход сам напрашивается. И что делать с ожиданиями? Нужен фоновый подход?
У меня все гораздо проще построено. Для заявок и стоп-заявок одинаково. Есть три таблицы ----------------------
Код
Tnt={[0]=0}; --таблица активных транзакций содержит trans_id,jts
Tor={[0]=0}; --таблица активных заявок 1-trans_id 2- номер в таблице QUIK 0-если выставляется , минус на удаление
Tso={[0]=0}; --таблица активных стоп-заявок 1-trans_id 2- номер в таблице QUIK 0-если выставляется , минус на удаление
Любая транзакция записывается в таблицу транзакций, Эта таблица обрабатывается в OnTransReply Если транзакция не прошла или прошла, то она удаляется из Tnt. Таким образом мы всегда знаем сколько транзакций отправили но не получили ответ. ----------------------- Если была ошибка, то отменяются действия по ней. Например транзакция на действия над существующей заявкой (удаляем или переставляем). ---------------------- Если выставляется новая заявка, то она записывается в таблицу активных, когда поступит сообщение об успешной отправки транзакции. ------------------------ Если пришло сообщение об исполнении или удалении то она удаляется из таблицы активных. ====================== Вот и весь алгоритм . ------------------------------- вот рабочий фрагмент конечного автомата, который обрабатывает эти три колбека
Код
elseif m==2 then --onOrder
local N=Tor[0]; local flags=t.flags local flag=flags&1; local num=t.order_num; local id=t.trans_id;
for i=1,N do
local s=Tor[i]; --s,id,js,num
if s[4]==num or (id~=0 and s[2]==id) then
if flag==0 then -- заявка не активна удаляем из списка активных если она есть в списке
if N>1 then Tor[i]=Tor[N] end Tor[N]=nil; Tor[0]=N-1;
else --заявка активная записываем ее номер
s[4]=num --записываем номер новой заявки по транзакции
if s[3]==0 then s[3]=Nor; Nor=Nor+1 end
end
break;
end -- заявка в списках
end
if flag==1 and id==0 then
N=N+1; Tor[N]={t.sec_code,0,Nor,num}; Nor=Nor+1 Tor[0]=N;--- активная заявка не найдена заявка выставлена не из скрипта создаем ее
end;
elseif m==3 then --onStopOrder
local N=Tso[0]; local flag=t.flags&1; local num=t.order_num; local id=t.trans_id;
for i=1,N do
local s=Tso[i]; --s,id,js,num
if s[2]==id or s[4]==num then
if flag==0 then -- заяка не активна удаляем из списка активных если она есть в списке
if N>1 then Tso[i]=Tso[N] end Tso[N]=nil; Tso[0]=N-1;
else --заявка активная записываем ее номер
s[4]=num --записываем номер новой заявки по транзакции
if s[3]==0 then s[3]=Nso; Nso=Nso+1 end
end
break;
end; -- таблица заявок,стоп-заявок инструмента
end
if flag==1 and id==0 then
N=N+1; Tso[N]={t.sec_code,0,Nso,num}; Nso=Nso+1 Tso[0]=N;--- активная заявка не найдена заявка выставлена не из скрипта создаем ее
end
elseif m==4 then
local x=t.status local msg=t.result_msg;
if x==3 or 2>x or x==15 then return end
---удаляем ошибочные транзакции сделок
message("status="..x..": транзакция "..t_mes[x+1]..">"..msg, 3)
local id=t.trans_id; local s,js; local N=Tor[0]; --ищем по заявкам
for i=1,N do s=Tor[i]; --s,id,js,num
if s[2]==id then js=s[3];
if js==0 then if N>1 then Tor[i]=Tor[N] end Tor[N]=nil; Tor[0]=N-1; return --отменяем выставление
else s[3]=-js; return end -- отменяем удаление
end
end
N=Tso[0]; --ищем по стоп-заявкам
for i=1,N do local s=Tso[i]; --s,id,js,num
if s[2]==id then local js=s[3];
if js==0 then if N>1 then Tso[i]=Tso[N] end Tor[N]=nil; Tor[0]=N-1; return --отменяем выставление
else s[3]=-js; return end -- отменяем удаление
end
end