VPM (Все сообщения пользователя)

Выбрать дату в календареВыбрать дату в календаре

Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 ... 32 След.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Идея (упрощённая модель) не использовать OnOrder / OnTrade ориентироваться на:
а) OnTransReply;
б) периодический просмотр таблиц orders / stop_orders;
с) фильтр по TRANS_ID.
- звучит вроде логично, но это polling-модель, не учитывает ряд критических проблем.

Попробую их формализовать. Это ровно то место, где ломается вся система!

Критическая проблема №1 "trans_id не живёт дальше заявки".
-------------------------
Ты опираешься на: trans_id > order > состояние
Но в реальности:  OnTrade НЕ содержит trans_id
значит: ты не можешь связать сделку с заявкой через trans_id?

Критическая проблема №2 "Таблицы QUIK - поток событий".
-------------------------
Ты предлагаешь: проверять orders / stop_orders при изменении количества записей. Проблема:

1) Нет гарантии атомарности?
T0 - появился order
T1 - сразу прошёл trade
T2 - ты прочитал таблицу
! ты увидишь: order уже частично исполнен НО не увидишь последовательность событий?

2) Ты теряешь событийную причинность?
FSM требует: ACK > TRADE > PARTIAL > FILLED
А таблица даёт тебе: balance уменьшился
! ты не знаешь:
* сколько было трейдов
* в каком порядке
* были ли дубли
* был ли cancel между ними

Критическая проблема №3 "Дедупликация невозможна"
-------------------------
В event-driven модели:processed_trades[trade_num]
В polling-модели: ты просто читаешь итоговое состояние
! ты не можешь:
* отфильтровать дубли
* гарантировать idempotency?

Критическая проблема №4 "Out-of-order ты вообще не контролируешь"?
-------------------------
QUIK: OnTrade > раньше OnOrder
Модель: таблица > уже обновлена
! ты даже не узнаешь, что был out-of-order?

Критическая проблема №5 "частичное исполнение (Partial fills) ломают модель"
-------------------------
Реальность: order 100
> trade 30
> trade 20
> trade 50
Таблица: balance = 0
! ты НЕ знаешь, было 3 сделки или 1 или 10?

Критическая проблема №6 "отмена/замена (Cancel/Replace) становится некорректным"
-------------------------
cancel > trade > cancel confirm
Polling увидит: order исчез
! ты НЕ узнаешь: был ли fill перед cancel сколько именно исполнилось?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
TGB,  Речь идет о подходах используемых HFT — High-Frequency Trading, а не технологиях.  
Цитата
VPM написал:
QUIK накладывает свои особенности, а у кого их нет, такова действительность. В своем подходе остановился на HFT исполнении и событийной модели, (опросы в качестве уточнений и восстановления). Конечно это не чистый HFT (ни для соревнований с фондами типа "Atto Trading Technologies LLC", которые уже говорят о наносекундах), у нас "QUIK latency" - высокий и нет прямого доступа к бирже. Но ряд подходов широко не обсуждаемых, можно использовать. Главным образом появляется возможность универсального движка, к которому можно цепляться как инвестиционными стратегиями, так HFT конечно в рамках QUIK. Этот подход требует и особой надежности системы (коду нужно крутиться продолжительное время)
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Nikolay,  Но ведь в любом случае ОПРОС будет более затратной операцией, чем реакция на событие. А значит нужна как минимум оптимизация процесса? nikolz,
Цитата
nikolz написал:
Опрос делается не по времени, а если изменился размер таблицы, т е запоминаете размер, в main на каждом цикле сравниваете с текущим, если изменился то опрашиваете.
Цитата
nikolz написал:
Например ,создаю таблицу активных заявок по каждому инструменту и обновляю ее по колбеку OnOrder и не использую таблицу заявок терминала ВООБЩЕ. Что существенно быстрее работает.
Что то типа такого?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
TGB,  В данный момент обсуждаю задачу как инженер разработчик, и не понимаю Ваш сарказм? Причем здесь "сумасшествие" если вопрос стоит об универсальном, оптимальном движке? Собственно как Вы любите. Возможно я не очень четко описал проблематику, или Вы у nikolz,  научились читать только то что Вам нужно. Еще раз. Ряд торговых задач решается только с HFT подходом даже в рамках QUIK (свечи из DS не нужны) именно текущее состояние восстанавливаем. Другие свечные стратегии тоже могут использовать движок.
Цитата
TGB написал:
Для принятия решений в роботе вам недостаточно текущего состояния вашего счета (которое отображается в его таблицах)
Ну конечно не достаточно, а виной тому асинхронный приход событий и заполнение таблиц.
Ну например: Критическая проблема. Out-of-order ты вообще не контролируешь?
QUIK:
OnTrade → раньше OnOrder
модель: таблица → уже обновлена

!ты даже не узнаешь, что был out-of-order. Такое может быть?

Или вот еще:  Дедупликация невозможна.
* В event-driven модели: processed_trades[trade_num]
* В polling-модели:  просто читаешь итоговое состояние
не возможно:
1) отфильтровать дубли;
2) гарантировать,  обеспечить (idempotency) , чтобы многократное выполнение одной операции приводило к тому же результату, что и первое, не меняя состояние системы повторно.
Может быть?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Тогда нужен правильный опробованный алгоритм, и архитектура этой polling-модели?

Но ведь QUIK скорее event-driven система, причем асинхронная, недетерминированная система? Следовательно, единственный способ сделать её детерминированной — это FSM + event pipeline.

Как у меня сейчас, главный тезис:
 * Таблицы QUIK — это snapshot состояния;
 * Callback            — это история событий.
 
Отсюда и единственно возможная архитектура и родилась к которой пришёл (и почему она сложная):
 * OnTransReply > intent
 * OnOrder          > связь trans_id > order_num
 * OnTrade          > факт исполнения
! это минимально достаточная модель, не "overengineering", включающая только те функции, которые необходимы для решения конкретной задачи.

Почему идея упростить, не отвечает данной постановки задачи? Потому что решаем задачу, "восстановления детерминированной истории исполнения, из не детерминированного потока событий QUIK"?

А проверка таблиц (polling) полезна и необходимо использовать в задачах:

1. Recovery / reconciliation. if exchange_position ~= internal_position then trigger_recovery() end
2. Watchdog. if order висит слишком долго > проверить таблицу
3. Fail-safe. если callback потерян > подтянуть через snapshot

Что не так делаю?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
TGB,  Согласен, Вы правы, можно проще, мой предыдущий подход излишне сложен. Но это стремление к максимальной отказоустойчивости и скорости.

Если использовать OnTransReply как единственный источник информации об отправке ордера, а для получения order_num и статуса исполнения периодически опрашивать таблицу orders (или stop_orders), фильтруя по trans_id. OnOrder и OnTrade в такой схеме не нужны, если задача позволяет мириться с небольшой задержкой (до 1 секунды) между исполнением и реакцией системы.
Это менее подвержено ошибкам, связанным с "out-of-order" событиями и наверняка проще. Для HFT это не подходит, но для обычной алготорговли – вполне!

Тогда Упрощённый алгоритм (без OnOrder/OnTrade)  будет выглядеть:
OnTransReply – только логируем успех/ошибку отправки. При успехе запоминаем trans_id как pending.
Периодический опрос таблицы orders (например, раз в 0.5-1 секунду) – выбираем заявки с trans_id из нашего списка pending. Получаем order_num, статус, исполненный объём.
Обновление позиций – при обнаружении изменений в balance (исполненная часть) вызываем PositionManager:update_position(...).
OnTrade не нужен – вся информация о сделках есть в таблице orders (поля balance, qty).
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Не открою большого секрета, что QUIK создавался и написан под брокерские команды. Отличительной чертой которых, является наличие узко специализированных специалистов, в то время как частному инвестору приходиться со всем справляться самому. В этом есть и преимущество, так и недостатки. Основной - это сложность построения инженерных торговых стратегий. Язык выбранный для автоматизации, на мой не профессиональный взгляд выбран оптимально, подходит тем и другим. Но вот реализация? Но этому собственно и посвящен настоящий сайт (а что тут еще есть?). Документация выложенная для пользователя, ну мягко говоря написана не на "русском языке".

Мое долгое вступление веду к тому, что для "частника" решившего заняться автоматизацией торгового процесса, или даже построением своей торговой системы, очень важна архитектура программы! Если задачей является, не просто "Кнопка срубить бабло", а инженерная стратегия арбитража или хедж - фонда, то процедурный стиль плохо подходит. Остается модульный стиль с четким разделением ответственности, и едиными стандартами данных на выходах. Это просто позволяет не переписывать код, а использовать одни и те - же уровни. Следовательно, можем создавать модульную математическую библиотеку внутри Lua - мозг системы.

QUIK накладывает свои особенности, а у кого их нет, такова действительность. В своем подходе остановился на HFT исполнении и событийной модели, (опросы в качестве уточнений и восстановления). Конечно это не чистый HFT (ни для соревнований с фондами типа "Atto Trading Technologies LLC", которые уже говорят о наносекундах), у нас "QUIK latency" - высокий и нет прямого доступа к бирже. Но ряд подходов широко не обсуждаемых, можно использовать. Главным образом появляется возможность универсального движка, к которому можно цепляться как инвестиционными стратегиями, так HFT конечно в рамках QUIK. Этот подход требует и особой надежности системы (коду нужно крутиться продолжительное время). Отладка, вот где проявляется то как устроен QUIK, что он возвращает, а документацией "Зачитаешься!". Вот и у меня, который раз виден финиш, и на новый круг в забеге.  :smile: Всем хорошего код!
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
"Умный в гору не пойдет, Умный гору обойдет"

Особенности QUIK или ровно то место, где ломается вся торговая система, основанная на событийной модели!

Ключевая проблема QUIK (которую поймал).  Факты:
* brokerref:
 > может отсутствовать в OnTrade;
 > может быть обрезан;
 > может не совпасть;
* trans_id  > вообще может не приходит в OnTrade;
* order_num  >  единственный стабильный идентификатор заявки.

Попытка использовать getOrderByNumber, вообще оказалась критической дырой (опасный костыль)

local order_info = getOrderByNumber(trade.class_code, trade.trade_num)  Это НЕ гарантируется QUIK! Почему? trade_num / order_num
1) нет гарантии наличия связи;
2) может вернуть nil или не тот ордер.

Правильное решение нашлось. НЕ искать order_num через trade_num. Вместо этого, использовать OnOrder как источник истины.


Производственный конвейер (Production pipeline)
1. В OnTransReply trans_id > сохраняем (pending);
2. В OnOrder order_num < связываем с trans_id;
А вот где рождается настоящая связь!
3. В OnTrade trade.order_num > находим ордер.

Следовательно, правильная модель связывания следующая Strategy > OrderExecutor > QUIK:
QUIK:  trans_id > order_num > trade_num
OnTrade:  trade > order_num > НАШ ORDER

Связка через order_num — это не просто улучшение, это - > единственный надёжный способ устранить position drift в QUIK, зафиксирую это как архитектурный стандарт!
Как задать комментарий в заявке?
 
Напоролся на эту же проблему - brokerref не передаётся в OnTrade, попытка идентифицировать ордер только по brokerref, закончилась неудачей? В результате мой PositionManager не может связать сделку с ожидающим ордером! Что это такое не знаю? Это проблема QUIK или отдельного брокера "не передаёт brokerref в OnTrade для сделок, исполненных по лимитным ордерам"?

У себя слепил из того что было:

Код
function OnTrade(trade)
    if not ctx or not ctx.instruments[trade.sec_code] then return end
    ctx.logger:info("OnTrade: %s %s qty=%d price=%.2f flags=0x%X brokerref=%s",
        trade.class_code, trade.sec_code, trade.qty, trade.price, trade.flags, trade.brokerref or "")

    -- Получаем номер заявки, связанной со сделкой
    local order_num = nil
    if trade.order_num and trade.order_num ~= "" then
        order_num = trade.order_num
    elseif trade.trade_num and trade.trade_num ~= "" then
        -- Пытаемся получить информацию о заявке по номеру сделки, если номер заявки недоступен напрямую
        local order_info = getOrderByNumber(trade.class_code, trade.trade_num)
        if order_info and order_info.order_num then
            order_num = order_info.order_num
        end
    end

    local event = ctx.pool:acquire()
    event.type_id = EVENT.TRADE
    event.sec_id = ctx.distributor.sec_to_id[trade.sec_code] or 0
    event.sec_code = trade.sec_code
    event.sec = trade.sec_code
    event.price = trade.price or 0
    event.qty = trade.qty or 0
    event.trade_num = trade.trade_num or 0
    event.flags = trade.flags or 0
    event.time = ctx.time:now()
    event.volume = trade.qty or 0
    event.brokerref = trade.brokerref
    event.order_num = order_num   -- сохраняем номер заявки
    ctx.queue:push(event)

    local pm = ctx.position_managers[trade.sec_code]
    if pm then
        pm:update_from_trade(trade, order_num)   -- передаём order_num
    end
    if ctx.executor then
        ctx.executor:on_trade(trade)
    end
end
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Посмотрим внимательней на код из примера выше. Если подходить более строго, в текущем виде это не стек, а очередь (bounded queue - ring buffer). Так как стек (LIFO) подразумевает push/pop, а  в примере используется паттерн: append → хранить N последних → читать историю

А это уже, скользящее окно (rolling window) — удобная структура для:
* индикаторов;
* нормализации;
* сигналов;
* инженерной разработки функций.
Так и в prop-архитектуре обычно используют RingBuffer / RollingWindow, а не сам Stack.

1. Проблема текущей реализации в примере кода:

table.insert(self.elements, value)
table.remove(self.elements, 1)

имеет сложность O(n), потому что table.remove(1) сдвигает всю таблицу (и про это на форуме писано переписано). Имеет значение и частота вызова, если это вызывается каждый тик, будет лишняя нагрузка.

2. Обычно в Production-решениях используется кольцевой буфер (Ring Buffer). Сложность: push = O(1)
Версия utils/ring_buffer.lua

Код
local RingBuffer = {}
RingBuffer.__index = RingBuffer

function RingBuffer:new(size)

    local o = {
        buffer = {},
        size = size,
        head = 0,
        count = 0
    }

    setmetatable(o, self)
    return o
end

function RingBuffer:push(value)

    self.head = (self.head % self.size) + 1
    self.buffer[self.head] = value

    if self.count < self.size then
        self.count = self.count + 1
    end
end

function RingBuffer:get(i)

    if i > self.count then
        return nil
    end

    local idx = (self.head - self.count + i - 1) % self.size + 1
    return self.buffer[idx]
end

function RingBuffer:last()

    if self.count == 0 then
        return nil
    end

    return self.buffer[self.head]
end

function RingBuffer:values()

    local out = {}

    for i = 1, self.count do
        out[i] = self:get(i)
    end

    return out
end

function RingBuffer:clear()

    self.buffer = {}
    self.head = 0
    self.count = 0

end

return RingBuffer
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Да нет Ziveleos, . Вы подметили суть. Сравнивать dofile и require можно долго, но без loadfile картина была неполной. И это важное уточнение. Вы не просто "напомнили", а добавили критически важный слой в понимание темы.  

dofile и require — это высокоуровневые обёртки над мощным механизмом loadfile. По аналогии из механики: loadfile — это рычаг, а dofile и require — просто разные насадки на этот рычаг для разных задач.

Внесу пояснения, чтобы зафиксировать этот "полный цикл":

1.  Фундамент — loadfile - это базовая функция. Она делает самое главное (и самое тяжелое) — читает файл с диска, компилирует его в байт-код и возвращает результат в виде *функции*. Но она её не выполняет.

2.  Утилитарный уровень — dofile - это просто удобная обёртка. Она сделала всю работу за нас, но лишила нас контроля. Это "выстрелил и забыл".

3.  Архитектурный уровень — require - Это уже не просто утилита, а менеджер зависимостей. Он использует loadfile для загрузки, и добавляет поверх этого кэширование.

А вот механика про перезагрузку модуля, загруженного через require, — это вообще высший пилотаж. Встречается для горячей перезагрузки кода в сложных приложениях (играх). Этот подход позволяет обновлять логику стратегии, не теряя состояние всей программы, что критически важно для долгоиграющих процессов.

Если есть свой пример для торговых приложений приведите?
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Просто пример:

Код
-- Класс Stack (LIFO)
Stack = {}
Stack.__index = Stack

function Stack:new(max_size)
    local o = {
        elements = {},      -- таблица-хранилище
        max_size = max_size or 5,  -- по умолчанию храним 5 элементов
        count = 0
    }
    setmetatable(o, Stack)
    return o
end

-- Добавить элемент наверх (push)
function Stack:push(value)
    table.insert(self.elements, value)
    self.count = self.count + 1
    
    -- Если превышен максимальный размер, удаляем самый старый (снизу)
    if self.count > self.max_size then
        table.remove(self.elements, 1)  -- удаляем первый (самый старый)
        self.count = self.max_size
    end
end

-- Удалить и вернуть верхний элемент (pop)
function Stack:pop()
    if self.count == 0 then return nil end
    local value = table.remove(self.elements)  -- удаляем последний
    self.count = self.count - 1
    return value
end

-- Посмотреть верхний элемент без удаления (peek)
function Stack:peek()
    if self.count == 0 then return nil end
    return self.elements[self.count]
end

-- Получить все элементы в порядке от старого к новому (для отображения)
function Stack:get_all()
    return self.elements
end

-- Получить все элементы в обратном порядке (новые сверху)
function Stack:get_all_reversed()
    local rev = {}
    for i = self.count, 1, -1 do
        table.insert(rev, self.elements[i])
    end
    return rev
end

-- Текущий размер
function Stack:size()
    return self.count
end


Как использовать в скрипте. Вместо отдельных массивов и ручного управления размером создаём стеки:

Код
-- В начале скрипта, после конфигурации
local deltaP_stack = Stack:new(20)   -- для нормализации (20 значений)
local deltaQ_stack = Stack:new(20)

local c_stack = Stack:new(5)         -- для отображения последних 5 значений
local alpha_stack = Stack:new(5)
local signal_stack = Stack:new(5)

-- для отображения исходных данных (опционально)
local deltaP_display_stack = Stack:new(5)
local deltaQ_display_stack = Stack:new(5)
local deltaOI_display_stack = Stack:new(5)
local deltaNB_display_stack = Stack:new(5)
local deltaNA_display_stack = Stack:new(5)
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
nikolz,  Вы правы, это классическая и очень правильная структура. Стек — идеальный выбор для хранения фиксированного числа последних значений (5, 20 и т.д.) благодаря дисциплине LIFO и операциям сложности O(1).

Но, если мы хотим реализовать стек в чистом Lua для QUIK, то не можем использовать встроенный stack, но можем создать его на основе таблицы. По чему ОПП удобно, таблица знает о себе все. Да можно быстрей, но архитектуру выбираем сами под задачу. Ведь так?

Для образного понимания смысла, мне нравятся проводить аналогии. В этом случае, можно сравнить 2 автомобиля. 1. 60 годов, для диагностики неисправностей которого требовался опытный механик. 2. современный авто где без подключения к компьютеру уже не разобраться. Так и использование мета таблиц в луа, это просто современный авто.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
TGB,  Мне вообще не понятно, зачем ими управлять, ведь это событие? Ну если первый способ, еще логичен включение как точки входа. То остальное зачем?
Очереди и двойные очереди в луа, Пример из книги Р.Е.
 
Йцукен, Речь шла прежде всего про универсальность, какой еще подход дает возможность, из одного подхода создавать разные очереди? Тут удивляться не чему, одна базовая и делай из нее  под свою задачу что нужно. А если это модуль то и сколько нужно. Возможно инженерия кода и заслуживает замечаний, но речь идет о самом подходе. В Вашем примере меня сильно смущает вот этот момент self[idx] = nil дыр не будет? А если все в порядке, то почему бы нет, все на первый взгляд элегантно?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Ziveleos,  Роберту Иерузалимски сравнивает dofile / loadfile. Мы же обсуждаем архитектуру production-системы. Это разные уровни задачи.

* loadfile действительно мощный инструмент когда, допустим  нужно перезагрузить стратегию без перезапуска всего скрипта.
* require — все таки правильно для модульной архитектуры.

OrderManager, RiskManager, StateMachine, Logger - это именно модули, а их лучше (правильно) подключать через require, так как возвращаем модуль, и тут не поспоришь.

Да и моя изначальная задача не в подключениях, а в контроле зависимостей. Но в любом случае, Вы подсветили полную картину подключений.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
А если такой вариант рассмотреть, создать специальный модуль или глобальную таблицу, которая будет управлять всеми зависимостями. Этот подход также может решить проблему избыточной передачи зависимостей, так как мы будем централизованно контролировать, какие библиотеки и модули подключаются?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Да, загрузили надо мне внимательней разобраться и переосмыслить подход.  :sad:
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Кажется уловил разницу.
а) dofile:
* каждый вызов → заново читает файл
* заново выполняет код
* выполняется в глобальном окружении?
* нет кэширования?
* нет изоляции
Это процедурный стиль.

б) require:
* выполняет файл один раз
* кэширует результат в package.loaded
* возвращает модуль
* позволяет строить граф зависимостей
* предотвращает двойную инициализацию
То есть это полноценная модульная система. Так?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
1. Не понял в чем разница?
2. Да, спасибо за вариант, про собственный флаг, даже не задумывался, взял на вооружение!
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
А вот то что я описываю, интересует в первую очередь этот момент.

Код
[QUOTE][USER=16131]VPM[/USER] написал:
-- Инициализация модулей в правильном порядке (с учётом зависимостей)

    -- 1. ExecutionLedger (зависит только от Logger, ссылка на StateMachine пока не используется)
    ExecutionLedger.init({ logger = Logger, stateMachine = StateMachine })

    -- 2. OrderManager (зависит от ExecutionLedger и Logger)
    OrderManager.init({
        ExecutionLedger = ExecutionLedger,
        Logger = Logger
    })

    -- 3. StateMachine (зависит от OrderManager, RiskManager, SignalEngine, utils, Logger)
    -- RiskManager и SignalEngine ещё не инициализированы, но init только сохраняет ссылки — это допустимо.
    StateMachine.init({
        utils = utils,
        OrderManager = OrderManager,
        RiskManager = RiskManager,
        SignalEngine = SignalEngine,
        Logger = Logger,
        ExecutionLedger = ExecutionLedger   -- <-- добавить
    })

    -- 4. RiskManager (зависит от StateMachine, SignalEngine, utils, Logger)
    RiskManager.init({
        utils = utils,
        StateMachine = StateMachine,
        SignalEngine = SignalEngine,
        Logger = Logger,
        config = {
            daily_loss_limit = daily_loss_limit,
            max_consecutive_losses = max_consecutive_losses,
            max_position_size = max_position_size,
            max_total_exposure = max_total_exposure,
            broker_comiss_stock = broker_comiss_stock,
            broker_comiss_fut = broker_comiss_fut,
            exchange_comiss_stock = exchange_comiss_stock
        }
    })

    -- 5. SignalEngine (зависит от utils, StateMachine, Logger и конфига)
    SignalEngine.init({
        utils = utils,
        StateMachine = StateMachine,
        Logger = Logger,
        config = {
            broker_comiss_stock = broker_comiss_stock,
            exchange_comiss_stock = exchange_comiss_stock,
            broker_comiss_fut = broker_comiss_fut,
            exchange_pay = exchange_pay,
            div = div,                     -- таблица дивидендов должна быть загружена ранее
            div_before_expiry = div_before_expiry,
            nalog = nalog,
            rate = rate,
            min_edge_abs = min_edge_abs
        }
    })

    -- 6. Watchdog (зависит от Logger, StateMachine, OrderManager, ExecutionLedger)
    Watchdog.init({
        Logger = Logger,
        StateMachine = StateMachine,
        OrderManager = OrderManager,
        ExecutionLedger = ExecutionLedger,
        config = {
            order_timeout = order_timeout,
            execution_timeout = 10
        }
    })

    -- 7. Recovery (если есть)
    Recovery.init({
        Logger = Logger,
        StateMachine = StateMachine
    })
    Recovery.recover()[/QUOTE]
   

Именно здесь, ни кто не по беспокоит, ни какие колбеки не прилетят, пока зависимости в модулях не установлены. А речь идет про разделение ответственности в модулях.

Что я делаю не так?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Ну хорошо, давайте по порядку. Вот вариант от TGB, Так?

Код
Сборка в главном скрипте

-- main.lua
require("core.order_engine")
require("adapter.quik_exchange")
require("adapter.callbacks")
require("strategies.simple_strategy")

function main()
    -- 1. Инициализация адаптера
    local exchange = QuikExchange:new("SPBFUT12345", "SPBFUT", "SiH5")

    -- 2. Инициализация ядра
    local engine = OrderEngine:new(exchange)

    -- 3. Передаём ссылку в callbacks
    set_engine(engine)

    -- 4. Создаём стратегию
    local strategy = Strategy:new(engine)

    -- 5. Главный цикл
    while true do
        local price_param = getParamEx(exchange.class, exchange.sec, "LAST")
        local price = tonumber(price_param.param_value)

        if price then
            strategy:on_price(price)
            engine:process()
        end

        sleep(100)
    end
end
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
TGB, Ну так огромная! А именно в локализации глобальных переменных для данного проекта. Да медленнее но Гарантированно!
Цитата
Nikolay написал:
Поэтому OnInit - это технический колбек, просто сигнализирующий, что код исполненный выше в body скрипта при его запуске, не привел к ошибкам.

Возможно так понятней о чем разговор, это кусочки кода

Код
dofile(path .. '\\QL.lua')
dofile(path .. "\\ContanGO\\Проект\\config.lua")

local utils = dofile(path .. "\\ContanGO\\Проект\\core\\utils.lua")
local Logger = dofile(path .. "\\ContanGO\\Проект\\core\\logger.lua")
local OrderManager = dofile(path .. "\\ContanGO\\Проект\\core\\order_manager.lua")
local StateMachine = dofile(path .. "\\ContanGO\\Проект\\core\\state_machine.lua")
local Recovery = dofile(path .. "\\ContanGO\\Проект\\core\\recovery.lua")
local SignalEngine = dofile(path .. "\\ContanGO\\Проект\\core\\signal_engine.lua")   -- пока не реализован, но должен считать edge
local RiskManager = dofile(path .. "\\ContanGO\\Проект\\core\\risk_manager.lua")     -- проверка лимитов
local Watchdog = dofile(path .. "\\ContanGO\\Проект\\core\\watchdog.lua")
local ExecutionLedger = dofile(path .. "\\ContanGO\\Проект\\core\\execution_ledger.lua")


И дальше:
Код
function OnInit()
    -- Логирование (ваш код)
    Logger.init(log_file)
    Logger.log("INIT", "", "Starting robot")

    -- Дополнительное логирование (опционально)
    do
        local log = _G.getScriptPath()..'\\arbitrage.log'
        toLog(log, "Start INIT robot arbitrage")
    end

    -- Объявление глобальных таблиц для хранения данных по инструментам
    exchange_pay = {}
    div_date = {}
    div_before_expiry = {}

    -- Инициализация контекстов для каждой акции из списка
    for stock in string.gmatch(ticker_list, "%a+") do
        local fut_code = futures_map[stock] or utils.findNearestFutures("SPBFUT", stock, 5)
        if fut_code then
            local lot_size = utils.safeParam("SPBFUT", fut_code, "LOTSIZE") or 1
            StateMachine.initContext(stock, fut_code, lot_size)

            -- Комиссия биржи
            exchange_pay[stock] = utils.safeParam("SPBFUT", fut_code, "EXCH_PAY") or 0

            -- Дата дивидендов (нужна реализация функции getDividendDate)
            div_date[stock] = getDividendDate(stock)

            -- Дивиденд до экспирации?
            if div_date[stock] then
                local exp_date = utils.safeParam("SPBFUT", fut_code, "MAT_DATE")
                div_before_expiry[stock] = exp_date and (tonumber(div_date[stock]) < tonumber(exp_date))
            else
                div_before_expiry[stock] = false
            end

            Logger.log("INIT", stock, string.format("Fut=%s lot=%d", fut_code, lot_size))
        else
            Logger.log("ERROR", stock, "No futures found")
        end
    end

    -- Инициализация модулей в правильном порядке (с учётом зависимостей)

    -- 1. ExecutionLedger (зависит только от Logger, ссылка на StateMachine пока не используется)
    ExecutionLedger.init({ logger = Logger, stateMachine = StateMachine })

    -- 2. OrderManager (зависит от ExecutionLedger и Logger)
    OrderManager.init({
        ExecutionLedger = ExecutionLedger,
        Logger = Logger
    })

    -- 3. StateMachine (зависит от OrderManager, RiskManager, SignalEngine, utils, Logger)
    -- RiskManager и SignalEngine ещё не инициализированы, но init только сохраняет ссылки — это допустимо.
    StateMachine.init({
        utils = utils,
        OrderManager = OrderManager,
        RiskManager = RiskManager,
        SignalEngine = SignalEngine,
        Logger = Logger,
        ExecutionLedger = ExecutionLedger   -- <-- добавить
    })

    -- 4. RiskManager (зависит от StateMachine, SignalEngine, utils, Logger)
    RiskManager.init({
        utils = utils,
        StateMachine = StateMachine,
        SignalEngine = SignalEngine,
        Logger = Logger,
        config = {
            daily_loss_limit = daily_loss_limit,
            max_consecutive_losses = max_consecutive_losses,
            max_position_size = max_position_size,
            max_total_exposure = max_total_exposure,
            broker_comiss_stock = broker_comiss_stock,
            broker_comiss_fut = broker_comiss_fut,
            exchange_comiss_stock = exchange_comiss_stock
        }
    })

    -- 5. SignalEngine (зависит от utils, StateMachine, Logger и конфига)
    SignalEngine.init({
        utils = utils,
        StateMachine = StateMachine,
        Logger = Logger,
        config = {
            broker_comiss_stock = broker_comiss_stock,
            exchange_comiss_stock = exchange_comiss_stock,
            broker_comiss_fut = broker_comiss_fut,
            exchange_pay = exchange_pay,
            div = div,                     -- таблица дивидендов должна быть загружена ранее
            div_before_expiry = div_before_expiry,
            nalog = nalog,
            rate = rate,
            min_edge_abs = min_edge_abs
        }
    })

    -- 6. Watchdog (зависит от Logger, StateMachine, OrderManager, ExecutionLedger)
    Watchdog.init({
        Logger = Logger,
        StateMachine = StateMachine,
        OrderManager = OrderManager,
        ExecutionLedger = ExecutionLedger,
        config = {
            order_timeout = order_timeout,
            execution_timeout = 10
        }
    })

    -- 7. Recovery (если есть)
    Recovery.init({
        Logger = Logger,
        StateMachine = StateMachine
    })
    Recovery.recover()

    Logger.log("INIT", "", "All modules initialized")
end


И что здесь не так?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
TGB,  Ну Вы опять, как школьник вызубривший урок наизусть, и ни грамма отступить от догмы, ну как тут не поверить, что перед нами отличник?

Ваши заключения абсолютно верны, и подход с использованием main для инициализации и работы в многозадачной среде действительно более эффективен в случае с QUIK, где важна производительность и отсутствие блокировок. Ну все этим пользуются, и я не исключение.

Но разве разговор про это? Ведь выше все подробно описал и даже пример минимальной структуры привел. Найдите там блокирующее body?

В кои веке, удалось найти что QUIK, что однозначно гарантирует. Ничего не произойдёт в скрипте пока OnInit не просигнализирует.

Nikolay,  вот пишет "Поэтому OnInit - это технический колбек, просто сигнализирующий, что код исполненный выше в body скрипта при его запуске, не привел к ошибкам. Ничего более. Делается это один раз при запуске. Поэтому там и могут быть только сугубо технические действия именно при запуске скрипта и ничего более."

Это как фазовый гарантированный переход! Из всего выше сказанного следует добавить фразу - "OnInit имеет смысл лишь как минимальная часть настройки среды"?

Мне нужна была гарантированная инициализация зависимостей в модулях между собой для контроля, простой их тусовки и замены. Дело в том, что тяжело в SciTe удержать контроль над зависимостями, а тут еще и наглядность. Именно здесь и проявляет свой характер OnInit (здесь прозрение, что хоть что есть гарантированного в QUIK и можно ставить себе на службу).

Nikolay,  Ваши замечания как всегда точны и логичны. Дело тут в том что в моем варианте зона body не рассматривалась, это просто зона локализации данных и переменных. Ну а последующие восстановления ни куда не деться будем тянуть из цикла маин, тут просто вариантов нет? Или я опять что то упускаю из вида?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
OnInit, или просто прозрение, которым хочется поделиться.
Ни так давно (по меркам вечности), на страницах этого форума зашел спор, суть которого можно выразить фразой "На фига козе баян".

Высказывались опытные разработчики скриптов, мнение разделись, одни утверждали: > "OnInit не нужен, всё можно сделать в main", другие что нужен, но зачем, так ни кто и не объяснил. Я придерживался простого мнения: кому нужен пользуемся, кому не нужен не пользуемся. Пока не встал у меня вопрос, "Как отслеживать зависимости между модулями"? Пришлось детально разбираться. И вот что получилось.

Если смотреть на архитектуру QUIK Lua строго с точки зрения production-дизайна — OnInit не просто "не лишняя", а ключевая точка композиции системы. Посмотрим системно.

1. Что реально делает QUIK.

Архитектурно терминал работает так:
1. Загрузка скрипта
2. Вызов OnInit(script_path)
3. Создание отдельного потока > main()
4. Далее event callbacks (OnOrder, OnTrade, OnQuote, ...)
  вызываются только если main() жив

Ключевой момент. > Все callback’и не будут вызываться, если main завершился? Следовательно,
main() — это lifecycle-контроллер.
А OnInit() — это фаза конфигурации до старта runtime.

2. Почему в production OnInit крайне полезен. Ошибочное мнение. > "OnInit не нужен, всё можно сделать в main"? Можно. Но это плохая архитектура. А правильная архитектурная роль OnInit — это:

2.1. Корень композиции зависимостей (Composition Root )
Именно здесь правильно:
* собирать зависимости
* инстанцировать модули
* связывать Core - Adapter - Strategy
* валидировать конфигурацию
* логировать старт

Это аналог:
* Spring Boot bootstrap
* ASP.NET Composition Root
* Dependency Injection container setup
Это три фундаментальных понятия современной backend-разработки, описывающих, как приложение запускается, собирается из компонентов и управляет своими зависимостями.

2.2. Fail-fast зона не менее важная. Если что-то не так:
* нет доступа к счёту
* отсутствует класс инструмента
* нет прав
* ошибка конфигурации
Лучше упасть до старта main, чем в рабочем цикле.

2.3. Разделение фаз
| Фаза      | Что происходит         |
| ---------- | -------------------------- |
| OnInit    | Конфигурация           |
| main      | Runtime                |
| Callbacks | Event-driven обработка |
Это даёт чистую архитектуру.

3. OnInit особенно удобно.

3.1. Связывание зависимостей (Wiring).
function OnInit(script_path)

   Config = require("config")
   Logger = Logger:new(Config.log)
   RiskManager = RiskManager:new(Config.risk)
   Strategy = MeanReversionStrategy:new(Config.strategy)
   Adapter = QuikAdapter:new()
   Core = TradingCore:new{
       strategy = Strategy,
       risk = RiskManager,
       adapter = Adapter,
       logger = Logger
   }

   Logger:info("System initialized")
end
Это наглядно, контролируемо и соответствует production-подходу.

3.2. Загрузка сохраненного состояния (persisted state). В OnInit удобно:
* восстанавливать позиции;
* читать журнал;
* восстанавливать FSM состояние;
* загружать последние известные заявки (last known orders)

3.3. Регистрация системных обработчиков. Можно централизованно регистрировать:
* OnOrder
* OnTrade
* OnStop
* Watchdog

4. Для чего НЕ стоит использовать OnInit. Не надо: запускать торговый цикл, делать в нем бесконечные sleep, ну и конечно обрабатывать рынок. Это не среда выполнения (runtime).

5. Production-подход к структуре QUIK-скрипта. И тогда просмативается правильный структурный подходС (skeleton):

-- ======================
-- Global references
-- ======================
local App = {}

-- ======================
-- OnInit
-- ======================
function OnInit(script_path)
   App = Bootstrap(script_path)
end

-- ======================
-- main runtime loop
-- ======================
function main()
   App:run()
end

-- ======================
-- Event callbacks
-- ======================
function OnOrder(order)
   App:onOrder(order)
end

function OnTrade(trade)
   App:onTrade(trade)
end

function OnStop()
   App:onStop()
end
Следовательно, так можем, централизовать систему, упрощаем тестирование, делает архитектуру масштабируемой.

6. Архитектурное мнение (строго production класса).
Если мы хотим строить, multi-instrument, risk-aware, state machine driven, persistent trading system, то OnInit обязателен как "корень композиции" (composition root). Без него система будет выглядеть процедурно и хаотично.

7. Ну и моя идея. > "В ней удобно выстраивать зависимости модулей между собой для наглядности и контроля". Оказалась, абсолютно правильный инженерный подход, уровеня промышленной архитектуры.
Разработчик, который фактически мыслит в терминах, Граф зависимостей (Dependency Graph), Управление жизненным циклом (Lifecycle management), Контролируемая начальная загрузка (Controlled bootstrap)

8. Что имеем, итоговое заключение. OnInit, не обязателен технически, и обязателен архитектурно в production подходе. Он делает систему, детерминированной, контролируемой, масштабируемой, безопасной, ну конечно удобной для отслеживания зависимостей самих модулей.
свободные средства для срочного рынка на едином счете
 
nikolz,  Спасибо.
свободные средства для срочного рынка на едином счете
 
Цитата
nikolz написал:
Есть две рекомендации 1) Перезаказать данные2) Пересоздать таблицу клиентского портфеля-------но если у вас в стакане все не активно, то проблема у сбера и они это знают и решают Если Вы сделаете как я написал, то проблему решат за 2 часа.
Уж ни знаю что случилось, пере заказал данные и фондовый заработал, на долго? не знаю, но это уже чудо.  :smile: VPM, Спасибо
свободные средства для срочного рынка на едином счете
 
Ну финам бкс, там ворочают такими счетами, что мне и не снились. Да, переводы не совсем  удобны, но и нет привязки к одному банку. А Если учесть что фондирование сегодня на уровнях 1%, то нужно хорошо подумать, что лучше?
свободные средства для срочного рынка на едином счете
 
Попробовал "Алор" кое что есть интересное, но пока не однозначно. Классический брокер, средней руки, деньги ходят по реквизитам, кто знаком поделитесь мнением?
свободные средства для срочного рынка на едином счете
 
Nikolay, Да решение классное на этот момент оптимальное!  :smile:  Я тоже сбежал.
Но у меня там приличный портфель, и "срочка" иногда нужна. НО по фондовому тоже ни чего не работает. Из приложения приходится рулить.
свободные средства для срочного рынка на едином счете
 
А если серьезно, возможно у кого еще было подобное? Возможно что то нужно поменять в настройках, рабочего места?
свободные средства для срочного рынка на едином счете
 
От общения с их тех. поддержкой "кровь стынет в жилах", дождусь не позднее 17 марта 2026  :smile:
свободные средства для срочного рынка на едином счете
 
не  *  это не ругательство - это аббревиатура Единый Брокерский Счет, была пока таланты не взялись за дело. Много у кого есть но как доп. сервис. Эти же решили кардинально. В копилочку талантов.
свободные средства для срочного рынка на едином счете
 
Не у меня круче!
После того как, головы брокера Сбер посетил  * , пропали торговые операции. Не актируется функции выставления заявок, ни из одного источника? Понятно, что накрутили что то на сервере? Обратился в тех. поддержку.
А сей час самое интересное. Вот ответ: "Мы начали работать с вашим вопросом № 260225-7000-942752 от 25 февраля 2026. Вернёмся с результатом не позднее 17 марта 2026. Если сроки изменятся, сообщим. Следить за статусом заявки удобно в разделе «Мои обращения»: sberbank.com/sms/ob"

А как Вам брокер?  У кого круче?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Нужно было просто  поправить  стратегию, и опять на те же "грабли!"

Разделение Ответственности.

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

Теперь задачу, можно свести к правильной архитектурной проблеме — не "как сделать ещё сложнее", а где проходят границы ответственности и кто от кого должен зависеть.
Правильное разделение ответственности, сформулирую правильный вектор этого подхода.

Напрашивается, разделение по типу ответственности:

A. Технологическое ядро (универсальное)
B. Адаптер к qLua (инфраструктура терминала)
C. Стратегический уровень (разные стратегии)

Вопрос стоит так, как избежать "Главной архитектурной ошибки", которая почти всегда возникает - слои смешаны, то есть:
* Стратегия знает про OrderManager;
* Recovery знает про FSM;
* FSM знает про детали брокера;
* Executor знает про стратегический контекст.
Это делает систему, сложно тестируемой, трудно расширяемой, опасной при добавлении еще одной или другой стратегии.


Сформулирую принципы, строго условно, выделив несколько слоев.

 Layer 1 — Технологическое ядро (Core Engine). Это НЕ про торговлю.
 
должнен быть:
* универсальным,
* не знать, что такое стратегия,
* не знать, что такое "акция" или "фьючерс".

Ему всё равно. Если завтра ты вставишь что то другое — ядро не меняется.

 Layer 2 — qLua Adapter Layer. Это тонкий слой интеграции.

за что отвечает:
* оборачивает getItem / getNumberOf
* обрабатывает OnTrade
* обрабатывает OnOrder
* делает sendTransaction
* нормализует данные

Это не стратегия. Это инфраструктурный адаптер. Ядро должно зависеть от интерфейса, а не от QUIK.

 Layer 3 — Strategy Layer.

Это единственный слой, где есть:
* SignalEngine;
* FSM арбитража;
* Логика входа/выхода;
* Крайние параметры (edge);
* Управление позицией

Стратегия НЕ должна, читать getItem, читать getNumberOf, знать class_code, знать brokerref. Она работает с абстракцией.

Сформулирую правильные зависимости (очень важно):
* Strategy > Core;
* Core > BrokerAdapter;
* BrokerAdapter > qLua.
И НИКОГДА наоборот.

"Стратегия не знает, что такое qLua. Core не знает, что такое конкретная стратегия".
свободные средства для срочного рынка на едином счете
 
nikolz, Как у Вас с брокером Сбер все корректно работает? Мне сегодня даже торговать не дает, молчу же что портфели по разному считают. В приложении одно в QUIK другое, чему верить не понятно? В приложении добавили в структуру портфеля срочный рынок, только забыли добавить метрики этой структуры. Чудеса и только. Видимо ни кто не научил  этих "горе специалистов" планировать и проводить  плановые работы? Хорошо, что только по кнопкам тыкают. Не хотелось бы с такими спецами на производстве столкнуться! В общем Сбер у меня чудит, что ни день то новые чудеса! :smile:
Не приходит полная версия OnTrade
 
В моей текущей реализации системы, это модуль  Watchdog, задача которого обеспечить непрерывный контроль в реальном времени. Он утверждает: "Прямо сейчас состояние допустимо".
И пусть цена идет куда угодно, пока состояние ни восстановлено, так как принимать решение все равно нельзя. Собственно это и есть механизм защиты от 10 сигма.
Не приходит полная версия OnTrade
 
Nikolay,  Рассуждения мои сводятся только к 3 коллбекам исполнения, дальше просто не заглядывал. Модель светофор не рассматривал, хотя показалась интересно нужно "покумекать".
Вы правы соображения субъективны, все выкладки чисто теоретические, так как систему только собрал еще даже не запускал. В соседней ветке описал от куда ноги растут.
Задача стояла быть уверенным что на какой то момент времени можно утверждать что все данные пришли. алгоритм "Рекомендация от разработчиков проста - взяли данные в колбеке и передали в main, и уже там с ней работает". То есть колбеки уже напихали нам отфильтрованную информации, работаем только с ней. Ну тут даже интуитивно видно что подход более оптимален, нежели описанный в примере от TGB. Обработку таблиц вызываем когда система само диагностировала несоответствие данных. 6 инвариантов или можно сказать 6 фазовых состояний замкнутый цикл. Все.
Да же если допустить, что событие несоответствия данных частое, то система перейдет в состояние опроса таблиц.

Здесь хочу добавить что рассуждения строил  от приказа стоп - лосса, но так как он в QUIK такой же лимитный, то все просто расширяю на исполнение всех лимитных ордеров?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Temporal Logic of Actions (TLA+) - метод, который взят за основу, — это не академическая теория, а активно используемая инженерная практика.

TLA+ применяется, критически важных системах, для верификации алгоритмов в распределённых системах, где ошибка может стоить очень дорого.
Крупнейшие технологические компании, такие как Amazon Web Services (AWS) и Microsoft, применяют TLA+ как Промышленный стандарт.
TLA+ помогает смоделировать взаимодействие нескольких торговых "ботов" на общем рынке и выявить сценарии, приводящие к "flash crashes" в Торговых алгоритмах.
Например, его используют для проверки протоколов консенсуса в блокчейнах (таких как Solana  и Tendermint ), платёжных каналов (Lightning Network ) и баз данных (Azure Cosmos DB ).

Суть. TLA+ позволяет описать систему не как код на Lua, а как набор состояний и переходов между ними. Это абстракция, в которой мы можем "забыть" о неважных деталях реализации и сосредоточиться на критической логике.

В моей текущей реализации системы это просто аналогия,  Watchdog — это непрерывный контроль в реальном времени. Он утверждает: "Прямо сейчас состояние допустимо".

TLA+ даёт принципиально иной уровень гарантий: "При любом развитии событий, даже самом невероятном, система никогда не войдёт в недопустимое состояние".
Эти два подхода не исключают, а идеально дополняют друг друга, обеспечивая максимальную надёжность.

Следовательно. Мы можем построить абстрактную модель системы на TLA+. Что позволит нам формально, а не только интуитивно, убедиться в том, что наши  доказательства (proof-sketch) верны, а архитектура действительно гарантирует безопасность счёта при любых мыслимых сценариях работы биржи и сети.

И это совершено иная концепция безопасности. "Ни гадать а быть уверенным"!
Не приходит полная версия OnTrade
 
TGB,  Не я не понимаю иногда то что Вы пытаетесь донести как истину в последней инстанции. А я бывает и ошибаюсь, читаю тех. литературу и пересматриваю подходы. Но так как Вы тему отказываетесь комментировать то смысла нет перепираться. Либо приводите убедительные доводы.
Не приходит полная версия OnTrade
 
TGB, За ссылку спасибо, но там столько не понятных для меня слов, что не хватает моей компетенции разобраться. За то хватает их чтоб прокомментировать Ваше сообщение выше. Глобально свое мнение не поменял.
Цитата
VPM написал:
1. Зачем повторять функциональность которую реализовали разработчики и которая отлажена, скорее всего лучше чем "призрачные" коллбеки (зависящие от кода main)
Прокомментируйте почему вдруг    "призрачные" коллбеки (зависящие от кода main)?
Как все реализовано разработчиками посвящен целиком этот сайт, а у меня даже мысли бы не было лезть туда куда ни надо.
Не приходит полная версия OnTrade
 
Цитата
Nikolay написал:
Цитата
VPM написал:
событийная модель может их решить элегантнее, чем простое увеличение таймаутов.
Все никак не могу понять о каких таймаутах речь и как потерянное событие решается без прямого обращения к данным. Если у вас есть датчик, то только его опрос даст данные, сам он их не пришлет - это простая железка.
Речь о двух независимых потоках, QUIK / колбек и Lua / main.
1. Колбеки прилетят быстрее факт очевидный пусть даже с маловероятным событием пропусками.
2. main мы вынуждены тормозить искусственно чтоб передавать управление ЦП. Вызывая обработку таблиц из цикла маин мы должны учитывать как минимум эту задержку?
3.  Сама система может находиться в 6 состояниях (модель куб состояний, где 8 вершин - фазовые переходы, 6 граней те самые инварианты), система замкнута следовательно может находится только в этих 6  состояниях. Кода находит расхождения в данных, она  восстанавливает данные путем уже опроса таблиц. Так как событие редкое то и опросы редки.
Все это и позволяет мне утверждать что будет более надежно обработано большее количество инструментов за меньшее время.  
Есть еще конечно и сама инженерия кода, но ведь обязательно кто то создаст надежный.
Не приходит полная версия OnTrade
 
Цитата
TGB написал:
Но интересно, что вы напишите на следующее.    Обрабатывая коллбеки и восстанавливая их результат, вы, по сути, повторяете (но в условиях неопределенности) работу которая выполняется в QUIK при формировании его таблиц.   1. Зачем повторять функциональность которую реализовали разработчики и которая отлажена, скорее всего лучше чем "призрачные" коллбеки (зависящие от кода main), так как это было давно (до появления QLua) и проще контролируется?   2. Полагаете, что вы квалифицированнее разработчиков?   3. Вы же вроде согласны с принципом "меньше дергаешься - реже падаешь". Вам нечем заняться и хочется поразвлечься с коллбеками?
А что тут комментировать, ЧУШЬ полная! Да и обсуждение совершенно о другом.
Не приходит полная версия OnTrade
 
Цитата
TGB написал:
VPM
  Забыл добавить: где доказательство безопасности счета?
А этого Вам не достаточно, или какие то слова не понятны?
Цитата
VPM написал:
архитектура с чёткими инвариантами и детерминированными компонентами позволяет предсказать поведение системы в любых ситуациях, включая сбои, и гарантировать, что она не совершит опасных действий (например, не превысит лимиты, не создаст дублирующий ордер).
Не приходит полная версия OnTrade
 
TGB, Я не пытаюсь навязать событийную модель как единственно верную. Я лишь показываю, что она даёт определённые преимущества в плане гарантий и детерминизма, которые могут быть критичны для сложных систем.

Ваш подход проще и для многих задач достаточен. Выбор зависит от требований к надёжности и готовности платить за сложность.

Если есть конкретные проблемы (например, потеря OnTrade), событийная модель может их решить элегантнее, чем простое увеличение таймаутов. Но если текущая система вас устраивает — нет смысла её усложнять.
Не приходит полная версия OnTrade
 
Я говорю о том, что архитектура с чёткими инвариантами и детерминированными компонентами позволяет предсказать поведение системы в любых ситуациях, включая сбои, и гарантировать, что она не совершит опасных действий (например, не превысит лимиты, не создаст дублирующий ордер). Это достигается не магией, а строгим проектированием. Именно поэтому в моей архитектуре колбэки не являются единственным источником истины. Они служат лишь для оперативного обновления состояния, но всегда дополняются регулярной сверкой с таблицами (reconciliation). Если колбэк потерян, система обнаружит это при следующем опросе и скорректирует состояние.

Таким образом, событийная модель не требует надёжности колбэков — она лишь использует их для уменьшения задержки!
Не приходит полная версия OnTrade
 
Nikolay,  CAP-теорема говорит, что в распределённой системе мы можем выбрать только две из трёх характеристик:
* Consistency,
* Availability,
* Partition tolerance.

Биржа — это отдельный узел, с которым у нас нет синхронной связи.
Мы выбираем Availability и Partition tolerance, жертвуя строгой консистентностью в реальном времени.

На практике, допускаем, что в любой момент наше локальное состояние может немного расходиться с биржевым. Но мы вводим механизмы, которые гарантируют, что это расхождение всегда будет обнаружено и исправлено за конечное время, и что в процессе расхождения система не совершит опасных действий (например, не превысит лимиты).

Именно это дают, в моем варианте, инварианты S1‑S6 и Watchdog.

Ваш подход тоже жертвует строгой консистентностью, но у него нет формальных гарантий, что в момент расхождения не будет ошибки. Вы просто надеетесь, что 1 секунд достаточно, чтобы всё "устаканилось"?
Не приходит полная версия OnTrade
 
TGB, А какие слова для Вас не понятны? Повторюсь, безопасность счёта можно доказать математически, событийная модель с инвариантами и реконсиляцией — единственный известный путь.
Не приходит полная версия OnTrade
 
TGB, Дело несколько в другом. Действительно, колбэки в QUIK не являются гарантированными, и любая система, работающая с реальной биржей, сталкивается с задержками, потерями и недетерминизмом. CAP-теорема здесь работает в полную силу, в распределённой системе, где биржа — это внешний, неподконтрольный нам узел.

Однако, из этого не следует, что событийно-ориентированная архитектура бессмысленна?

Напротив, она предназначена именно для того, чтобы жить в мире, где события могут теряться, приходить не в том порядке или с задержкой. Разница между вашим подходом (опрос таблиц + OnTransReply) и событийной моделью не в том, что событийная модель предполагает надёжность колбэков, а в том, как она обрабатывает неопределённость!
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
"Но если задача стоит построить систему, которая должна быть математически корректной, отказоустойчивой и масштабируемой, без событийной модели и формальных инвариантов не обойтись.
Потому что её поведение можно доказать на реальной торговле на любых объёмах и с любыми стратегиями, а не просто протестировать!
" В соседней веточке подняли на мой взгляд, очень важную тему, сколько угодно можно осуждать тему "система принятия торговых решений", но если не решена задача описанная выше, все становится просто бессмысленно. Перестраивая свою систему безопасности именно к такому выводу подошел. И хочу привести ряд подходов.
Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 ... 32 След.
Наверх