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

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

Страницы: 1 2 3 4 5 6 7 8 9 10 11 ... 30 След.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Казалось бы, на этом можно и закончить обсуждение подхода, понятно что двойственность при создании индикатора, проявляется на этапе выбора длины окна необходимого для анализа (Периода) и это всегда есть дилемма лага и шума.

Но не все так просто!

"Эффект бабочки" объясняет, почему микроскопическая погрешность или шум в начале математических расчетов полностью искажает итоговый результат. И не учитывать этот фак при создании алгоритмов просто нельзя. Суть проблемы, в контексте трейдинга и анализа временных рядов (биржевых графиков) в следующим, когда для построения индикатора или прогноза используются рекуррентные формулы (текущее значение зависит от предыдущего рассчитанного значения, например EMA или как у меня SuperSmoother), математическая погрешность начинает лавинообразно нарастать прямо внутри одной свечи. Есть несколько решений ухода от проблемы. Можно по экспериментировать с FIR-фильтрами (например, smooth = (4*p0 + 3*p1 + 2*p2 + p3) / 10) или внести жесткие ограничения или коэффициент затухания в расчеты.

У себя выбрал наиболее простой - "Отказ от тиков в пользу баров". Внутри свечи определенного тайм фрейма, цена совершает хаотичные колебания, их невозможно просто индифицировать в рамках текущего тайм фрейма, (нужно менять масштаб). Здесь правило вычисления заключается, выполнять пересчет исключительно на этапе закрытия свечи (Close[i] ~= Close[i-1]), это позволяет избежать данного эффекта. При этом исключается из рассчета текущий бар, и тем самым вносим в алгоритм расчета Лаг. Для полноты картины можно представить, расчеты проводятся на месячном тайм фрейме (потеряли текущий месяц). А для HFT и 1 минута сравнима с месяцом на месячном тайм фрейме. Согласитьсь для принятия торговых решений, картина не приглядная, вывод, не позволитильная роскошь игнорировать "настоящее", оперируя только прошлым?

Возникает задача масштаба.
Вспоминаем что данные (свечи) это фрактальная запись "квантованных" данных (свечи имеют вложенную, само подобную структуру).  
Одно из решений (вариант А) - многомасштабный (мульти фрактальный) анализ. Вместо игнорирования текущего бара, расчет ведется одновременно на нескольких вложенных тайм фреймах.
 * Старший тайм фрейм задает глобальный тренд (фильтрует шум). У себя часто для этого использую мгновенный тренд (Decycler 2013г John F. Ehlers).
 * Младший таймфрейм используется как "микроскоп", внутри текущей незакрытой свечи торгового тайм фрейма. Это позволяет видеть структуру движения "здесь и сейчас", не дожидаясь закрытия старшего бара.
 * На среднем, торговом - система принятия решений.

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

Если не уходить в тяжелую теоретическую физику, элементы этого анализа на практике можно свести к, и внедрению через:
1) Квантование по объему (Volume Delta Vectors), анализ направления и силы рыночных ордеров (Ask/Bid) внутри свечи как векторов.
2) Фазовые портреты, то есть построение графиков в осях "Цена — Скорость изменения цены" (P и dP/dt). Это убирает фактор времени и показывает циклы системы.

Здесь важно, помним! Рынок — это не замкнутая квантовая система. Шум здесь не всегда случаен, и внешние шоки (новости), мгновенно разрушают построенные волновые функции (происходит коллапс волнового пакета). И еще одно, легко нарваться на проблему "переподгонки", из-за обилия параметров (фазовые пространства, волновые функции, матрицы перехода) очень легко создать модель, которая идеально объясняет прошлое, но абсалютно бесполезна в реальном времени.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Если с вычислительной математикой индикатора разобрались, то возникает следящая проблема - интеграции индикаторов в терминал QUIK.
 Проблема А - нулевого (текущего) бара ("Дерганья");
 Проблема Б - утечки памяти при некорректном кэшировании.

Вот и у меня. Поскольку индикатор ADX_v4 использует рекурсивные фильтры (ZLEMA, SuperSmoother) и исторические лаг-компенсаторы, каждый тик на текущей (незакрытой) свече будет необратимо перезаписывать историю, если не изолировать расчеты.

Памятка. "Строгая техническая спецификация оптимизации под архитектуру QUIK".

1. Проблема А. Дерганье и Накопления Ошибок на Последнем Баре.
Терминал QUIK вызывает функцию индикатора на каждом входящем тике (сделке) для текущего индекса свечи I == Size().
 * Опасность для рекурсии: В строке zlema[I] = current_zlema на незакрытом баре записываем промежуточное тиковое значение в массив по индексу I. На следующем тике (внутри той же секунды/минуты) функция вызывается снова. Но в ячейке zlema[I-1] всё еще лежит значение прошлого закрытого бара, а вот в zlema[I] уже сидит искаженное значение от предыдущего тика. Происходит "эффект бабочки", рекуррентные коэффициенты накапливают ошибку внутри одной свечи. Когда свеча закроется, её историческое значение окажется полностью искаженным.
 * Техническое решение проблемы заключается, запретить на незакрытом баре изменять постоянные исторические массивы. Расчет текущего тика должен производиться во временных (фиктивных) переменных, а запись в историю — происходить строго в момент фиксации (закрытия) бара.

2. Проблема Б. Оптимизация Хранения и Очистка Буферов (Память).
 * Если робот работает на мелком таймфрейме (M1) или собирает историю за несколько месяцев, стандартные таблицы Lua (DX = {}) раздуваются до десятков тысяч элементов. Это приводит к деградации кэша процессора и тормозам QUIK при вызове table[I-1].
 * Техническое решение (Кольцевой буфер). Нашему безлаговому ADX для расчета не нужна вся история от сотворения мира. Ему нужен хвост глубиной в P * 3 баров. Будем использовать метод ограничения глубины буфера. При превышении максимального индекса принудительно удаляем самый старый элемент из таблиц с помощью table.remove(t, 1) или прямой очистки индексов t[I - max_depth] = nil. Здесь очень важный момент не наделать в таблице "дыр".

Финальный боевой код с аппаратной защитой под QUIK, в сборку нужно интегрировать:
а) защитный механизм проверка фиксации бара;
б) кольцевая очистка кэша, предотвращающая утечки памяти.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Дирекционные Индексы (+DI и -DI), в место классического подхода, обработал фильтром ZLEMA (Zero Lag EMA). К самому ADX применил SuperSmoother фильтр из DSP. Теперь, когда линия ADX стала идеально гладкой за счет двухполюсного фильтра SuperSmoother, ее можно и нужно сравнивать со своим прошлым значением. В экономико-математическом смысле знак первой производной (ADX[t] - ADX[t-1]) теперь четко отделяет фазу тренда от фазы коррекции (флэта), без ложного шума - пилы. Поскольку лаг компенсирован, а линия гладкая, математическая логика определения Тренд / Коррекция, теперь сводится к простому правилу:
 Если (ADXcurrent > ADXprevious) — рынок находится в активной фазе тренда (неважно куда, вверх или вниз).
 Если (ADXcurrent <= ADXprevious) — тренд затухает, рынок перешел в фазу коррекции, консолидации или флэта.

Что касается компенсации лага самого ADX, мы можем применить к нему тот же математический подход, что и для DI, но адаптированный под специфику итоговой линии. Поскольку ADX сглажен с помощью SuperSmoother, у него уже очень низкий фазовый сдвиг по сравнению с классической EMA. Идеальное инженерное решение здесь — линейная экстраполяция Тейлора первого порядка, идея  ( 2 * Out - Out1), но примененная строго на выходе из фильтра SuperSmoother. Это подтолкнет линию вперед по вектору движения, сохранив ее гладкость. Связка ZLEMA + SuperSmoother + Линейный разгон полностью меняет поведение ADX.

Применение векторного анализа к индексу DX (Directional Trend Index) — это высший пилотаж в разработке и не только торговых систем. Переход от скалярных величин к векторным позволяет полностью переосмыслить природу тренда!

В классическом варианте DX — это скаляр (абсолютная величина, не имеющая направления). Посмотрим на его каноническую формулу, в числителе, DX всегда положителен (применен модуль). Он показывает только интенсивность разбалансировки рынка. Возникает некий инженерный тупик. Глядя на скалярную величину, например DX = 70, робот знает, что на рынке мощный тренд. Но он физически не знает, куда этот тренд направлен — вверх или вниз. Ему приходится делать второй логический шаг, запрашивать значения pDI и mDI и сравнивать их между собой. Это создает лишние ветвления в коде, увеличивает лаг принятия решения.

Зафиксирую. Вектор в двумерном пространстве определяется двумя характеристиками:
 * длиной (модулем)
 * и направлением (углом).
 
Мы можем представить состояние рынка на каждом баре как точку на координатной плоскости, где:
 * Ось X — это сила быков (pDI).
 * Ось Y — это сила медведей (mDI).
Следовательно, состояние рынка — это радиус-вектор vec{V} = (pDI; mDI). Здесь достигается и взаимно дополнительность этих двойственных отношений (ортогональность).

Но анализировать абсолютные координаты неудобно, так как они зависят от волатильности. Нам нужен вектор относительного импульса vec{DX}. Для этого, убираем модуль из формулы и получаем знаковый векторный дифференциал. Теперь наш вектор  живет в одномерном векторном пространстве на оси [-100; +100]. Получаем геометрический смысл вектора:
vec{DX} -> +100 Вектор силы рынка полностью развернут в сторону покупателей. Чистый, экспоненциальный бычий тренд.
vec{DX} ~= 0      Вектор находится в точке баланса. Силы равны, на рынке абсолютный флэт.
vec{DX} -> -100  Вектор силы полностью направлен в сторону продавцов. Чистый медвежий тренд.

Когда мы превратили DX в вектор, мы можем применять к нему операции математического анализа, недоступные для обычного ADX.  
Экономико-математические преимущества векторного анализа:
А. Скорость вектора (Первая производная dvec{DX}/dt ) В место того чтобы просто смотреть, растет ADX или падает, мы считаем разность векторов между текущим и прошлым баром: Velocity vec{DX}[t] - vec{DX}[t-1] Если Velocity > 0 при положительном vec{DX} — тренд вверх ускоряется. Если Velocity} < 0 при положительном vec{DX} — тренд вверх замедляется (сигнал на фиксацию прибыли, хотя цена еще может идти вверх).

Б. Ускорение вектора (Вторая производная d^2vec{DX}/dt^2) Acceleration = Velocity[t] - Velocity[t-1] Это чистый опережающий квантовый фильтр. Момент, когда Acceleration меняет знак с плюса на минус на вершине тренда, происходит за 2–3 бара до реального разворота цены. Это позволяет разгружать позицию прямо на "хаях"!!!

Для интеграция вектора в алгоритм, нужно модифицировать финальную часть нашей функции ADX.Log_v4. Вместо того чтобы отдавать классический ADX (сглаженный скаляр) и две линии DI,
мы заставим ядро вычислять вектор vec{DX}, сглаживать его через SuperSmoother и отдавать три чистые векторные величины:
 * V_ADX — Векторный ADX (направление и сила тренда в одной линии от -100 до +100.
 * V_Velocity — Скорость изменения вектора (импульс).
 * V_Acceleration — Ускорение (опережающий триггер).
 
Теперь трейдер или робот читает векторный анализ примерно так:
 Вход в Лонг (Идеальная точка). V_ADX выше нуля, V_Velocity > 0 и V_Acceleration только что пересекло ноль снизу вверх.
 Выход из Лонга (Опережающий). V_ADX все еще высоко в положительной зоне (например, +65), но V_Acceleration уже упало ниже нуля, а V_Velocity развернулось вниз. Цена еще растет на инерции, но векторное поле рынка сигнализирует -> топливо у покупателей закончилось.

Переход на векторный анализ DX убирает из кода робота, громоздкие конструкции сравнения линий и сводит весь анализ тренда к знакам трех чисел. У себя я ни чего не убираю, просто собираю все в таблицу и распаковываю уже в OnCalculate или роботе тот формат который требуется.
По аналогии переписал и RSI.

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

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

Что на практике дает подход для трейдинга.

1. Цены. Проблема абсолютных значений широко известна. Обычные индикаторы считают приращения в пунктах или рублях/долларах (Delta = Price1 - Price2), то есть Актив меняется в цене. Если акция выросла с 10 до 100 рублей, то колебание на 2 рубля в начале истории — это огромный сдвиг на 20%, а в конце истории — это незаметный шум в 2%. В результате, Классические индикаторы на больших исторических периодах "сходят с ума". Они недооценивают волатильность в прошлом (когда цена была низкой) и переоценивают её в настоящем (когда цена высока).

2. Разности цен vs Отношения цен. Переход на отношения (Ratio = Price1 / Price2) или логарифмы отношений (100 * ln(Price1 / Price2)) кардинально меняет свойства данных. Зафиксирую.
 * Разности цен - Арифметический подход (АП)
 * Отношения цен - Геометрический подход (ГП)
Зависимость от масштаба, АП - Высокая (искажает историю при росте актива);  ГП - Полностью отсутствует (масштабо независима).
АП - Нельзя сравнивать разные активы (например, Сбербанк по 260 руб. и Газпром по 130 руб.); ГП - Можно сравнивать любые активы между собой напрямую.
Природа рынка, АП - Не соответствует рыночной логике (рынок мыслит процентами доходности); ГП - Идеально соответствует (отражает процентное изменение капитала).

3. Математическое преимущество, непрерывная доходность (ln) В моем коде используется 100 * log( l0 / l1). В эконометрике это называется непрерывно начисляемой доходностью (log-returns). Это даже лучше, чем просто отношение, по трем причинам:
 а) Симметричность падения и роста, если цена выросла со 100 до 200 (+100%), а потом упала с 200 до 100 (-50%), обычные проценты не симметричны. Логарифм же даст, ln(200/100) = 0.693 и ln(100/200) = -0.693. Они равны по модулю. Для осцилляторов и индикаторов силы тренда (как ADX) это критически важно — сила движения вверх и сила движения вниз измеряются линейно одинаково.
  б) Аддитивность, сумма логарифмов приращений за 5 дней строго равна логарифму приращения за весь 5-дневный период. С обычными разностями или процентами это не работает.
  с) Нормализация, например True Range (TR), в ADX движение (+DM; -DM) делится на Истинный Диапазон (TR), если и числитель, и знаменатель переведены в логарифмы, то ADX становится абсолютно очищенным от цены "индексом чистого процента".

4. Переписал у себя классический ADX Уайлдера, реализовал с этим подходом. Не которые плюсы и минусы идеи, для индикатора ADX, вышли на поверхность.
 а) Плюсы. Идеальный бэктест, на исторических данных больших промежутках (за 5–10 лет) индикатор должен работать одинаково хорошо на всем промежутке. Его не придется пере оптимизировать из-за того, что цена акции выросла в 5 раз. Мультирыночность, один и тот же робот с одними настройками ADX сможет анализировать и фьючерс на индекс МосБиржи (десятки тысяч пунктов), и дешевую акцию (несколько рублей). Устойчивость к гэпам, на утренних гэпах логарифмический ADX не будет улетать в космос так сильно, как классический, поскольку он сглаживает экстремальные скачки.
 б) Но есть и Риски и подводные камни. Проблема околонулевых цен, если актив стоит копейки (например, фьючерс вблизи экспирации), деление на очень маленькое число или логарифм близких к нулю долей может вызвать резкие скачки - шум. Возможна потеря чувствительности на флэте. На низко волатильном рынке логарифмические приращения становятся очень маленькими, и скользящие средние внутри ADX могут начать "слипаться", выдавая ложные сигналы затухания тренда. Чтобы не возникало Искажение, нужно что бы функция (True Range) в расчетах тоже была переведена на логарифмы! Если pDM и mDM считаются через log(Ratio), а fTR считает классический (High - Low) в пунктах, то формула (100 * pDM / iTR) математически разрушится (будем делить проценты на рубли).

В Результате использование отношений и логарифмов вместо разностей — это идея, которая приближает технический анализ к законам количественного анализа (Quant Trading). Она полностью решает проблему старения исторических данных. А главное, за чем нужно следить при реализации в коде, должна соблюдаться абсолютная однородность данных. Все компоненты (High, Low, Close, TR) внутри этого расчетного ядра, должны быть переведены в логарифмические приращения.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Важное уточнение.
В этом подходе нужно четко понимать и определять двойственность, как фундаментальное отношение двух состояний системы, то есть - это уже абсолютно вычисляемая конструкция. Двойственность — не какая то абстрактная философия, а механизм возникновения структуры через различие. То есть двойственность — это фактически, примитив операционного различия.

Главное, для алготрейдинга в том что, двойственность:
* можно вычислять,
* можно кодировать,
* можно измерять,
* можно строить как ядро модели.

Если убрать вычислимую двойственность, то ломается вся архитектура концепции. Потому что именно отношения:
* создают напряжение,
* напряжение рождает градиент,
* градиент рождает поток,
* поток рождает структуру рынка.

В конечном итоге в концепции, появляется очень красивая структура.
# Скаляр. Абсолютное состояние.
# Двойственность. Отношение состояний.
# Градиент. Направление изменения отношений.
# Векторное. поле Организованная структура отношений.
# Дивергенция. Локальное усиление/затухание отношений.
# Ротор. Циклическое перераспределение отношений.

И более того, практически все современные теории, физика, DSP, экономика и трейдинг построены именно на отношениях. Вот и у нас.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Важно! Или просто о сложном, сложном (для меня), а для кого - то возможно просто. Почему градиент?

Для единого понимания смыслов, просто зафиксирую.
 * Градиент (grad) — операция, которая превращает скаляр (скорость) в вектор, появляется дополнительный параметр - направление. Показывает направление роста скалярной величины и скорость этого роста. Мгновенное значение векторного поля.
 * Обратная операция - Дивергенция (div), операция, которая превращает вектор в скаляр. Показывает, является ли точка "источником" или "стоком" векторного поля. Эти понятия из векторного анализа, составляет основу этого анализа.
 * Излагая концепцию, нужно сказать о третьей операции - Ротор (rot), операция, которая превращает вектор в другой вектор. Описывает вращательную способность поля вокруг точки. Направление вектора ротора определяет ось вращения по правилу правой руки, а длина — интенсивность завихрения.

Собираем все вместе. Задача, рассуждаем о движении цены, как результате некоторого взаимодействия. В рамках данной концепции, представляем цену как некое физическое тело (абстракция), движущееся под воздействием сил спроса и предложения. Это далеко не ново, например в квантитативных финансах (Quant Finance), графики часто анализируют через уравнения математической физики.
Наша задача сводится к проведению междисциплинарной аналогии, между физическими смыслами (природными операционными механизмами), понятиями из цифровой обработки сигналов (DSP) их переносе на финансовые графики. В этой модели движение цены рассматривается как сложный волновой сигнал, состоящий из наложения множества циклов разной природы. И введем сюда векторный анализ. Как? Выше есть в моих постах описание куба состояний (законченная модель цикла). Каждая вершина рассматривается, как начало координат векторов i,j,k, за которыми закрепляются понятия не только из трейдинга но и физические и всей данной концепции и даже метафизические. Такая модель легко расширяется, можно добавлять бесконечно параметры. Для этого куб вписывается в единичный шар, поверхность которого можно описывать бесконечным множеством векторов (параметров). Ну конечно в рамках смыслов!

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

Представление рынка как поля состояний. Тогда интерпретация рынка будет выглядеть так: "Рынок — это не «волны цены», а стохастическая адаптивная система потоков ликвидности с нелинейной обратной связью". Следовательно, FFT, векторный анализ, DSP, гидродинамика, двойственность, становятся не буквальной физикой рынка, а языком приближений для описания структуры потока ордеров. А ключевая идея всей модели и данной концепции: "рынок — это не объект, а поле состояний", которое мы можем оживлять, внося динамику процессов, ну и конечно смыслы.
И тогда:
цена — локальное состояние,
ликвидность — распределение потенциала,
ордер-флоу — поток,
моментум — локальная скорость поля,
волатильность — амплитуда колебаний,
тренд — устойчивое направление градиента.

А всего лишь ввели гдраиент, градиент здесь нужен не как математическая формула ради формулы, а как механизм рождения направленности из состояния!
Не могу реализовать память через CSV файл
 
Главная причина, почему Ваш скрипт "ничего не помнит" — критические синтаксические ошибки, из-за которых Lua-интерпретатор в QUIK просто ломается и не может корректно выполнить код.

Главные ошибки в Вашем коде:
1. Синтаксический слом в CheckLine: Конструкция end elseif написана с ошибкой. В Lua нет elseif после end. Из-за этого функция вообще не компилировалась. Сломанный массив - строка Trades[] в OnInit — это некорректный синтаксис Lua. Выдаст ошибку.
2. Потеря переменной current_line. В функции OnTrade вы вызываете remove_line_from_csv(secondfile, current_line). Но current_line была локальной переменной внутри CheckLine. В OnTrade она всегда равна nil или старой глобальной пустышке. Скрипт не понимал, какую строку удалять.
3. Бесконечный цикл без выхода. В main() запущен while do_main do sleep(1000) end, но флаг do_main нигде не меняется на false. Скрипт зависнет навсегда при остановке.
4. Конкуренция за файлы. Файл secondfile открывается в режиме "r" (чтение), но при удалении строки Вы пытаетесь стереть его через os.remove прямо во время работы, что в Windows часто блокируется, если хэндл не освобожден или пересекается с другими функциями.

Попробуйте так. Исправленный скрипт. Этот вариант исправляет логику работы с файлом покупок (fibobuys.csv). Вот что изменилось.
Исправлен синтаксис.
Удален сломанный elseif в CheckLine и пустой массив Trades[].
Скрипт теперь корректно запускается терминалом QUIK.
Добавлена функция поиска строки (find_line_by_price). Теперь скрипт при продаже сканирует файл fibobuys.csv, находит точный номер строки, где лежит цена этой покупки, и передает этот индекс в функцию удаления. Если точная цена не найдена (например, из-за проскальзывания), он удаляет первую строку (принцип FIFO).
Безопасная перезапись файла. Вместо рискованного удаления файла через os.remove (который часто блокируется Windows, если файл занят QUIK), скрипт выкачивает строки в массив, очищает файл через режим "w" и записывает обратно только нужные данные.
Добавлен корректный OnStop. Теперь при остановке скрипта кнопкой в QUIK цикл в main останавливается корректно, а хэндлы файлов закрываются.

Скрипт все еще остается учебным и требуется доработать логику. Да и архитектуру тоже. Используйте код предварительно проверив, выкладываю как есть просто исправленный Ваш вариант. Удачи!
Код
-- Настройки торговой стратегии
local class = "QJSIM" 
local sec = "SBER" 
local account = "NL0011100043" 
local LotSize = 1 
local step = 0.02 --> Нужно проверить не уверен что так?
local limits = 10 

-- Служебные переменные
local tid = 0 
local trz_comment = "FIBO-2 --> " 
local uprice = nil
local dprice = nil
local TradeNums = {}
local do_main = true
local climits = 0

-- Пути к файлам
local csv_path = getScriptPath().."/FiboTrades.csv"
local secondfile = getScriptPath().."/fibobuys.csv"
local CSV = nil

function OnInit()
    CSV = io.open(csv_path, "a+")
end

-- Округление
function math_round(roundIn, roundDig)
    local mul = 10^roundDig
    return math.floor((roundIn * mul) + 0.5) / mul
end

-- Отправка транзакции -->  Проверьте параметры?
function LimitSpot(operation, SpotPrice)
    tid = tid + 1
    local transaction = {
        ["TRANS_ID"]   = tostring(tid),
        ["ACTION"]     = "NEW_ORDER",
        ["CLASSCODE"]  = class,
        ["SECCODE"]    = sec,
        ["OPERATION"]  = operation,
        ["QUANTITY"]   = tostring(LotSize),
        ["PRICE"]      = tostring(SpotPrice),
        ["ACCOUNT"]    = tostring(account),
        ["EXECUTION_CONDITION"] = "PUT_IN_QUEUE",
    }
    local res = sendTransaction(transaction)
    if res ~= '' then
        message(trz_comment..'Transaction Error! '..res)
    else
        message(trz_comment..'Transaction Success! ID = '..tid)
    end
end

-- Проверка файла цен для продажи или покупки
function CheckLine(number)
    local current_line = 1
    local same = 0
    local is_sold = false
    
    local CheckFile = io.open(secondfile, "r")
    if CheckFile then
        for line in CheckFile:lines() do
            local val = tonumber(line)
            if val then
                if val == number then same = same + 1 end
                -- Если цена в файле ниже или равна текущей — продаем по этой фиксации
                if val <= number then 
                    LimitSpot('S', number)
                    is_sold = true
                    break 
                end
            end
            current_line = current_line + 1
        end
        CheckFile:close()
    end

    -- Если совпадений нет, лимит не исчерпан и мы не продали — покупаем
    if not is_sold and same == 0 and climits < limits then 
        LimitSpot('B', number) 
    end
end

-- Удаление строки из CSV (безопасное переписывание)
function remove_line_from_csv(filename, line_to_remove)
    local lines = {}
    local input_file = io.open(filename, "r")
    
    if input_file then
        for line in input_file:lines() do
            lines[#lines + 1] = line
        end
        input_file:close()
    end

    local output_file = io.open(filename, "w")
    if not output_file then return end

    for i, line in ipairs(lines) do
        if i ~= line_to_remove then
            output_file:write(line .. "\n")
        end
    end
    output_file:close()
    message(trz_comment.."Строка "..line_to_remove.." удалена из базы покупок.")
end

-- Функция поиска строки по цене для удаления при OnTrade
function find_line_by_price(filename, price_to_find)
    local input_file = io.open(filename, "r")
    if not input_file then return nil end
    
    local line_number = 1
    for line in input_file:lines() do
        if tonumber(line) == price_to_find then
            input_file:close()
            return line_number
        end
        line_number = line_number + 1
    end
    input_file:close()
    return nil
end

function main()
    message(trz_comment..'Start.')
    while do_main do
        sleep(1000)
    end
end

function OnStop()
    do_main = false
    if CSV then CSV:close() end
    return 1000
end

function OnParam(class1, sec1)
    if class1 == class and sec1 == sec then
        local last_param = getParamEx(class, sec, "last")
        if not last_param or last_param.param_value == "" then return end
        
        local price = math_round(tonumber(last_param.param_value), 2)
        
        if uprice ~= nil then
            if price <= dprice then
                dprice = dprice - step
                uprice = uprice - step
                message(trz_comment..'Price-- -> '..price)
            elseif price >= uprice then
                CheckLine(price)
                dprice = dprice + step
                uprice = uprice + step
                message(trz_comment.."Price++ -> "..price)
            end
        end
    end
end

function OnTrade(trade)
    if trade.sec_code == sec and trade.class_code == class then
        -- Инициализация сетки по первой сделке
        if uprice == nil then
            uprice = trade.price + step
            dprice = trade.price - step
            message(trz_comment..'Grid placed success!')
        end

        -- Проверка на дубликаты сделок
        for i = #TradeNums, 1, -1 do
            if TradeNums[i] == trade.trade_num then return end
        end
        TradeNums[#TradeNums + 1] = trade.trade_num

        local Op = ""
        local t = bit.band(tonumber(trade.flags), 4) -- 4 = sell, 0 = buy
        
        if t == 0 then 
            -- ЛОГИКА ПОКУПКИ
            Op = "Buy"
            climits = climits + 1
            message(trz_comment.."buy "..trade.price)
            
            local wr = io.open(secondfile, 'a+')
            if wr then
                wr:write(trade.price.."\n")
                wr:flush()
                wr:close()
            end
        else 
            -- ЛОГИКА ПРОДАЖИ
            Op = "Sell"
            climits = climits - 1
            message(trz_comment.."Sell "..trade.price)
            
            -- Ищем строку с ценой, которая послужила триггером для продажи
            local line_idx = find_line_by_price(secondfile, trade.price)
            if line_idx then
                remove_line_from_csv(secondfile, line_idx)
            else
                -- Если точной цены нет, удаляем первую попавшуюся строку (FIFO)
                remove_line_from_csv(secondfile, 1)
            end
        end

        -- Логирование в общий файл FiboTrades.csv
        if CSV then
            local TradeLine = os.date("%x %X", os.time(trade.datetime))..";"..
            trade.class_code..";"..
            trade.sec_code..";"..
            trade.trade_num..";"..
            trade.order_num..";"..
            Op..";"..
            trade.price..";"..
            trade.qty.."\n"
            
            CSV:write(TradeLine)
            CSV:flush()
        end
    end
end
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Да и торгуем пунктами в условиях вероятностного исхода. А для оценки системы нужны статистические метрики, такие как мат. ожидание, профит фактор, % прибыльных сделок как минимум.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Nikolay,  Именно так, как Вы описали, я начинаю рассуждать, когда сильно усердствовал над какой то идеей, а по результатам в системе принятия решений "пшик".

Эмоциональность моих высказываний не сколько не выше, допустим подобных высказываний: "Дайте прибыли течь ...". В приведённом Вами отрывке, хотя бы можно выделить алгоритм и даже запрограммировать его. Если кого то, смущает слово "ракета", так это просто наследство от автора подхода, который рассмотрен в посте. На мой взгляд даже подчеркивает авторство.

Но давайте по порядку. Определимся с рядом постулат для отражения общих смыслов и понятий.

Первое. Давайте на некоторое время отрекаемся от дисциплин: физики, химии, биологии и так далее и уж тем более от психологии. Что объединяет все эти дисциплины - математика. В нашем случае просто как единый язык междисциплинарного общения. Но не забываем про фундаментальный законы, которые на своем языке описывают эти дисциплины.

Второе. Нам нужно определить с понятием "Сигнал", отречься от аналогового сигнала и полей типа (E*H). Будем рассуждать о цифровом бинарном сигнале (0;1). Чтобы перейти к цифровой аналогии аналогового сигнала, нужно еще постараться с преобразованиями и не наделать в них ошибок. Тем немение, подобная азбука Морзе, позволила создать вычислительные машины, в том числе на которых общаемся.

В таком подходе, у нас остались фундаментальные законы (природные операционные закономерности) на чем собственно Мир держится, математика как язык общения и описания этих закономерностей.

Вспомним как поступали 150 лет назад, имея только карандаш и лит бумаги. Да технический анализ (1 - покупки; 0 - продажи), запись 111100 = тренд повышательный с коррекцией. С тех пор ничего не изменилось так как в самом движении есть фундаментальные вещи. Как работал волновой анализ Элиота так и продолжает работать. Как была фрактальность на рынках так и есть. Микро структуры вложены в более старшие (игрушка - Матрешка). Как читали ленту в поисках ввода/вывода крупных средств на/из рынка, так и читают.

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

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

Касаемо подхода который описал, так его легко проверить, дописать счётчик, и проверить статистику. Попадаем в 5% все ОК. У нас нормальное распределение, нет на "помойку".

В мое описании только принципы, нет важных деталей, это должен сделать каждый сам. Например, у себя делаю компенсацию лага. Руководствуясь соображениями теории вероятностей, стандартное отклонение (StDev) отражает волатильность актива (ширину "шума"). По статистическому правилу нормального распределения (или правилу 68-95-99.7), около (68%) всех ценовых движений укладываются в пределы 1 стандартного отклонения от среднего. Около (68%) всех ценовых движений укладываются в пределы 1 стандартного отклонения от среднего. Умножая StDev на 0.5, вы получаете так называемое медианное ожидаемое значение шума (половина от стандартного диапазона). Но и этого не достаточно. Его нельзя на прямую применять, у себя я еще считаю градиент и использую как коэффициент.

Ведь вещь очевидная что результаты получим разные!
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Дециклер Элерса работает на потоке данных. Это динамический фильтр нижних частот. Он не пытается "угадать" линию тренда через всё окно данных, а просто отсекает быстрые колебания (шум), оставляя плавное движение. Что в свою очередь позволяет утверждать об отсутствии перерисовки в момент прихода нового бара (чего не скажешь про регрессию).
Для построения качественного вероятностного канала на базе Дециклера Элерса, нужно рассчитать центральную линию и динамическое отклонение. Основная фишка здесь в том, что разница между ценой и Дециклером — это и есть очищенный шум. На нем сигма работает точнее всего.

Классическая ловушка адаптации параметров в тех. анализе заключается в том, "Чтобы адаптировать индикатор, нужен другой индикатор, который сам требует адаптации". Этот подход вносит двойной лаг. Сначала запаздывает индикатор адаптации, а затем он с опозданием меняет параметры Дециклера. К тому времени, когда период адаптируется, рыночная фаза может уже смениться.
Для разных тайм фреймов на MOEX (акции, фьючерсы) характер шума сильно меняется, поэтому параметр Cutoff (длина волны, которую мы считаем шумом) нужно как то все таки адаптировать.
За основу, выбрал  простотой логический подбор параметров Cutoff и Sigma с возможность ручной коррекции при необходимости.

Например, Тайм фрейм - D1 (День); Cutoff(Период) = 10–15; Sigma(Mult) = 2.0; Логика. На днёвках тренды инертны. Малый Cutoff позволяет Дециклеру быть быстрой средней, почти не отставая от основной тенденции. M60 (Час); 24–30; 2.5. Отсекаем суточный шум. Увеличенная сигма (2.5) нужна, чтобы не реагировать на волатильность внутри торговой сессии и ловить только реальные выбросы. Ну и так далее.

Поскольку Дециклер — это идеальная "центральная ось", стратегия строится на возврате цены к математическому ожиданию после статистического выброса. Торговая стратегия получила название "Дециклерный Реверс" - (Mean Reversion), коих полно на "просторах" и нет смысла повторяться. Но есть Важное дополнение. К ней нужен Фильтр "Тренд vs Флэт".

Дециклер Элерса дает уникальную возможность оценить силу тренда через наклон линии. Если расстояние между ценой и Дециклером стабильно растет, а линия направлена круто вверх — рынок в импульсе. Против него торговать сигму нельзя, можно получить проход вдоль границы. Здесь лучший сигнал, когда цена вылетает за 2-ю сигму, а сама линия Дециклера горизонтальна. Это классический боковик, где вероятность возврата к середине максимальна. В своем канале цена проводит ~95% времени. Выход за границу 2-й сигмы при использовании Дециклера — это почти всегда истинный импульс или перекупленность, а не просто ошибка запаздывания средней.

Нашлось и математическое решение - "Индекс Относительной Мощности" (Trend/Sigma Ratio). Все что нужно ввести коэффициент TSR - это отношение скорости тренда к "энергии шума". Логика здесь следующая.
* Если Скорость Тренда > Сигма — это Ракетный импульс. Любые сигналы Z-score на разворот игнорируются. Мы едем по тренду.
* Если Скорость Тренда < Сигма — это Шумный боковик или затухающий импульс. Здесь Z-score имеет максимальный вес.
Почему это логично:
  1. Защита от "Ракет", не шортить инструмент, который растет вертикально (где темп роста 1\% в бар, а шум всего 0.2\%).
  2. Фильтрация флета, заключается в понимании факта, что выход за Сигму в боковике — это дар, а в тренде — это ловушка.
  3. Ну и конечно Нормировка. Сравнивая проценты со скоростью, мы получаем безразмерный коэффициент - Здоровья тренда.

В своей реализации сделал инженерное предложение. Добавил в "подвал" к осциллятор Z-Prob, вторую линию — TSI (Trend Strength). Теперь:
 * Когда Z-Prob в зоне экстремума, а TSI идет вниз — это Идеальный вход.
 * Когда оба на максимуме — это Сильный импульс (не трогать!).
Добавив расчет этого коэффициента TSI в фабрику, для финальной фильтрации сигналов получил фактически мозг будущего робота.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Nikolay,  Извините, обращение выше это nikolz, к Вам не имеет ни какого отношения. Просто ошибся со вставкой имен.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Nikolay,  Вы самостоятельно разучились думать? Это сильно заметно.  :smile:  

Попробуйте 2 словами сказать в чем Ваша идея?
От себя добавлю сильно не увлекайтесь ИИ, проверяйте. ИИ ошибается, а главное не умеет мыслить, это просто аппроксимация большого количества данных. Не более.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Nikolay,  Вы точно описали фундаментальный момент, фильтр сам по себе не прогнозирует. Он только трансформирует сигнал, чтобы выделить определённые компоненты: тренд, шум, циклы. Никакой магии для предсказания будущего он не даёт. Вы мне показалось вкладываете в само понятие Сигнал слишком физический смысл. Наши данные - цена в определенный момент времени. Запись а бар - это с родни квантованию. У такой запись есть диапазон колебания, спин и период этого колебания. Но главное здесь фрактальность, меньшие гармоники вложены в более старшие тайм фреймы, это важно для понимания о чем идет речь.

Что реально мы можем делать с фильтром.
* Сглаживание и выделение компоненты, можно? можно.
* Краткосрочное экстраполирование, можно? можно. На маленьком шаге (5–10% от окна) можно попытаться продолжить движение по фазе, можно. Возьмем тайм фрейм месячный 30 * 0.05 = 1.5 дня месячного тф. Чтоб такой тренд сломать нежно очень постараться, а мы отследим это, с помощью циклической составляющей или на меньших тф другими способами. Ни кто не мешает масштабировать подход на день или час. Ни какой магии?

Второе, то что у нас есть в этом подходе, осциллятор Детрендер. Компонента очищенная от тренда. Когда мы считаем Сигму через RMS от High-Pass фильтра, мы меняем саму парадигму.

Вот какая математика здесь:

1. С точки зрения вероятностей, "Стационарность шума"? Вычитая Дециклер из цены, мы проводим операцию детрендинга. Полученный остаток (HP) — это почти стационарный ряд. Например классические полосы Боллинджера (от SMA) предполагают, что цена распределена нормально вокруг среднего. Но цена нестационарная величина (у неё есть тренд).
В описанном подходе, Сигма теперь описывает стандартное отклонение "белого шума" рынка. С точки зрения статистики, выход за 2 Сигмы в нашей модели — это не просто цена далеко ушла, а "энергия" рыночного шума превысила критический порог. Вероятность того, что шум вернется к среднему уровню этой энергии, математически гораздо выше, чем возврат трендовой составляющей к цене.

2. Смысл трейдинга можно свести к оценкам "Энергия vs Расстояние". Мы измеряем амплитуду текущего рыночного цикла. Смысл, строим канал не вокруг цены, а вокруг текущей способности рынка совершать колебания. Трейдинговый инсайт здесь можно свести к:
 * Если канал расширяется — рынок переходит в фазу раскачки (дистрибуция или накопление).
 * Если сужается — рынок сжимает пружину.
Поскольку Сигма очищена от лага тренда, сужение канала происходит мгновенно при затухании активности, а не через 20 баров.

3. Строгая математическая модель (Z-Score).  Для робота будем использовать метрику  Z = (Price - Basis) / RMS(HP). Это число показывает, сколько "единиц текущего шума" содержится в отклонении цены (можно четко через тики или % или вообще в валюте). Здесь уже Стратегия принимает взвешенное решение, если Z > 2.0 - Статистическая аномалия (Энергия выброса истощена). Вероятностный реверс. Если Z < 0.5 - Состояние покоя. Любое движение — это шум. Ждем импульса. Система принятия решений имеет четкий вероятностный сигнал. Не говорю уже что ее можно подкрепить функциями принадлежности.

4. Практический вывод для Order Management. Интерпретируем канал как "Границы рыночного дыхания": Нижняя/Верхняя границы — это уровни, где рыночный шум достигает своего естественного предела для данного момента времени. В отличие от Боллинджера (по мне так вообще подход на помойку), наш канал не пухнет просто потому, что цена улетела вверх (тренд). Он расширяется только если увеличился разброс между тиками.

В итоге данного Инженерного подхода. Мы получили адаптивный волатильный коридор. Если цена вышла за него, значит, она движется быстрее, чем рынок способен шуметь. Это либо начало сильного направленного тренда, либо ложный выброс, который будет поглощен. Расчет этого Z-Score даст нам четкое понимание — пора бить по стакану в обратку? Конечно нельзя сбрасывать со счетов "мощность" трендовой компоненты - тренд нужно учитывать.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
nikolz,  Любой у кого есть подключение может сделать запрос и сравнить подходы. А главное абсолютно не понятно, что вы своим постом хотите сказать?

Мы не обсуждали подходы волнового анализа, я лишь уточнил, что Элерс использовал, Динамический (DSP) подход. А преобразование Гильберта — это вершина безлаговой адаптации в концепции Элерса.  Джон Элерс понял, что искать все циклы на рынке бессмысленно — они постоянно сменяют друг друга. Вместо этого он применил Преобразование Гильберта для поиска одной, доминирующей в данный момент рыночной волны и расчета ее мгновенной фазы. Как это работает на примере, индикатора Hilbert Transform Homodyne Discriminator. Берется цена и создается ее копия, сдвинутая строго на 90 градусов по фазе (Квадратурная компонента Q), в то время как исходный сигнал — это (Синфазная компонента I). Математический трюк заключается в том что, имея вектор I и вектор Q, Элерс вычисляет Мгновенную фазу (Instantaneous Phase) рыночного цикла на каждом баре через арктангенс, arctan(Q / I). Скорость изменения этой фазы от бара к бару дает точную длину текущего доминирующего цикла.

Обсуждение идет вокруг безлаговой адаптации в концепции, и их применении при построении ценового канала, и дополнительных полезных метриках.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Nikolay,  Мне не понятно почему Вы делаете такой вывод? На чем основываетесь?

Цитата
Nikolay написал:
Что касается фильтра, то какой бы простой не использовали, это будет просто фильтрация, без определения значимых гармоник. И назначение - убрать шум. Никакого будущего не может быть предсказано. Т.е. тренд, направление фильтром не определяется.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
VPM написал:
Но и это еще не все!  
Ниже покажу строго математически преимущество подхода. И прогностическое поведение, ну хорошо правильно наверно сказать, опережающее поведение индикатора. Чуть доделать нужно, все дело в особенностях реализации адаптивных индикаторов под QUIK. Не понимаю когда и как нужно обновлять область хранения переменных при смене параметра Cutoff? Да ну их сделаю период (Cutoff) логичным к тайм фреймам.

Уже даже нельзя называть даже индикатором - это целая фабрика по производству метрик.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Ну и второе. Сравнение Преобразования Гильберта (Hilbert Transform) в интерпретации Элерса и Преобразования Фурье (Дискретного/Быстрого — DFT/FFT) — это фундаментальная дискуссия о том, как извлекать циклы из нестационарных временных рядов (цен). Если говорить простым языком, выделяя смысл, Фурье пытается разложить график на фиксированные синусоиды, а Гильберт измеряет мгновенные параметры одной доминирующей волны. А главное, используя подход Преобразования Фурье мы упираемся опять в туже проблему - имя которой ЛАГ.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Nikolay,  Чуть - чуть не Так.
Я и пишу о  сравнении подходов в построении ценовых каналов и выборе метода. Сравнение этих двух инструментов — это битва статистики (Регрессия), против радиотехники (Дециклер). Несмотря на внешнее сходство (область применения оба строят канал), у них принципиально разная природа. Уделяю внимание Дециклер останавливаюсь подробна на не лишь только по тому что он и здесь показал лучший результат.

Вот основные отличия:

1. Математическая основа.
а) Регрессионный канал. Статистическая (прошлые данные). Строится методом наименьших квадратов (LMS). Он пытается провести прямую линию (или полином) так, чтобы сумма квадратов отклонений всех цен в выбранном окне была минимальной. Это статическая аппроксимация прошлого.
б) Дециклер Элерса. Цифровой фильтр (поток данных). Это динамический фильтр нижних частот. Он не пытается "угадать" линию тренда через всё окно данных, а просто отсекает быстрые колебания (шум), оставляя плавное движение.

2. Реакция на новые данные (Проблема перерисовки).
а) Регрессионный канал. Крайне нестабилен на краях. При появлении новой свечи угол наклона всей линии регрессии может измениться, что приведет к пересчету всего канала назад в прошлое.
б) Дециклер. Обладает свойством  причинно-следственной связи (каузальности). Значение на баре №144 зависит только от баров №1–144 и никогда не изменится от того, что произойдет на баре №145. Это делает его пригодным для реальной торговли без самообмана.

Назначение.
а) Регрессионный канал. Скорее оценка перекупленности в фазе флэта.    
б) Дециклер Элерса. Определение тренда и волатильности.

Границы (Сигма).
а) Равномерны по всей длине.              
б) Адаптивны (меняются с волатильностью).

Отсюда, разный подход к использованию,
* наклон Регрессии как глобальный фильтр (куда смотрим?),
* а выход за Сигму Дециклера как локальную точку входа (когда бьем?).
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
"Вот скажи мне, американец, в чём сила? ... Я вот думаю, что сила в правде. У кого правда — тот и сильней"

Из области "красивых графиков" в область количественных финансов (Quantitative Finance). Битва статистики против радиотехники — простое сравнение инструментов для строительства ценовых каналов:  
* HMA (Средняя Халла — Золотой стандарт борьбы с лагом),
* Zero-Lag EMA (DEMA/TEMA - Использует эффект двойного сглаживания),
* Регрессия (),
  против фильтра Ehlers Decycler (инструмента из области цифровой обработки сигналов DSP, выделяет низкочастотную составляющую - долгосрочный тренд). Просто математика.
Не буду описывать различия, это легко можно сделать, написав код, или с помощь ИИ проанализировать. Сразу к Сути.

Для поддержки единообразных смыслов:
* "Quantitative Finance - финансовая математика. Это область, объединяющая математические методы, статистику, программирование и финансовую теорию для оценки активов, управления рисками и торговли на финансовых рынках."
* Decycler — это результат классического метода декомпозиции. Суть процесса заключается в разделении данных на две составляющих.    
               
                  Модель: Цена (Price) = Тренд (Дециклер) + Цикл (Шум)

Дециклер использует хирургический подход, он не просто усредняет всё подряд, а "вырезает" высокочастотный шум, оставляя чистый тренд. Результатом является мгновенная линия тренда.
Вторая составляющая модели - Детрендинг = Цена - Дециклер = Цикл (Шум)

В результате этой операции устраняется ценовой тренд, и на графике остается только циклическая, осцилляторная составляющая, колеблющаяся вокруг нулевой линии. Это помогает лучше видеть краткосрочные циклы, не искаженные общим направлением рынка.
Ключевым моментом является тот факт, что для эффективного детрендинга, Дециклер должен быть построен таким образом, чтобы его задержка (lag) была минимальной, иначе вычитание даст ложные сигналы. Собственно этим и обусловлено преимущество мгновенной линии тренда, справляться со статистически значимым объемом данных при минимальном лаге. Вместо того чтобы строить скользящую среднюю (которая всегда отстает),  берется фильтр высоких частот (High-Pass Filter), который выделяет только "рыночный шум", и вычитает этот шум из текущей цены.

Логика, Decycler = Price - HighPass(Price)

Так как фильтр высоких частот по своей природе имеет практически нулевое запаздывание, итоговая линия (Дециклер) движется синхронно с ценой, оставаясь при этом гладкой. Для оценки разброса (волатильности) и построения вероятностных каналов "сигма-каналы" (а-ля полосы Боллинджера) выбор средней критичен. Задача — иметь стабильную базу, которая не "дергается" на шуме, иначе границы канала будут постоянно перестраиваться. Вот и получается, что для вероятностной оценки лучше всего подходит Дециклер Элерса. Он обеспечит "центровку" внутри текущего движения цены, без излишнего запаздывания EMA и без хаотичности HMA. Разброс (сигму) в этом случае лучше считать не как StDev от цены, а как StDev разности (Price - Decycler).

Но и это еще не все!  :unamused:
Робот, торгующий опционами
 
На мой взгляд, вот интересная статья: "Сермяжная логика определения стоимости опционов". Erik Naiman. Более детально описано в его книге "Путь к финансовой свободе".

Рассматривает простой, пример определения цены опциона с учетом всех основных факторов влияния на его стоимость, с точки зрения финансовой логики, прикладной точности и практической полезности. Статья для тех, кто хочет быстро понять экономическую целесообразность продажи колл-опционов. Простая и наглядная логика без сложной математики с привязкой к реальным акциям, дивидендам и процентам. Упрощения в расчётах форварда и дивидендов, это не строгая математическая модель (не Black-Scholes).

Статья даёт полезную основу для понимания того, как оцениваются опционы через будущую стоимость акций, премию и волатильность. А главное помогает сформировать интуитивное чувство ценности опционов на рынке. Для практического, полезного применения, в QUIK или Excel, можно сделать, короткую схему или таблицу, которая визуализирует коридор безубыточности, премию и вероятность попадания цены в коридор, как это делает автор. Или же доработать, привести к более структурированному виду,
Баг SearchItems с datetime.mcs
 
nikolz,  Странно даже слышать? Целиком и полностью согласен с funduk, ! Конечно задокументировать свой косяк это исправление половины недочёта, что уже хорошо, и подтверждает признание.  Но кто не ошибается? Признали отлично, но вопрос почему дальше не исправляем? Все это тянем. Читаем самую продаваемую книгу постулат  >  "По образу и подобию". Почему это важно исправить, а не плодить 120 имен для одного параметра. Уже и ни  знаю нужно - ли подобные вещи объяснять в программировании? Но в инженерии по одному месту настучать нужно.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Извините, не верно вставил код:
Код
  -- Унифицированная нормализация order_num
local function normalize_order_num(order_num)
   if order_num == nil then return nil end

   -- Приводим к строке
   local s = tostring(order_num)

   -- Убираем пробелы
   s = s:match("^%s*(.-)%s*$")

   -- Убираем ведущие нули (важно для QUIK)
   s = s:gsub("^0+", "")

   -- Если стало пусто > это ноль
   if s == "" then s = "0" end

   return s
end
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Возможное решение - устранения классической проблемы.

Добавил жёсткую нормализацию order_num во всех точках, задача устранить классическую проблему number vs string и "невидимые" несовпадения ключей.
Идея проста, единая общая функция нормализации + использование её везде (save / get / delete / compare).

[CODE][-- Унифицированная нормализация order_num
local function normalize_order_num(order_num)
   if order_num == nil then return nil end

   -- Приводим к строке
   local s = tostring(order_num)

   -- Убираем пробелы
   s = s:match("^%s*(.-)%s*$")

   -- Убираем ведущие нули (важно для QUIK)
   s = s:gsub("^0+", "")

   -- Если стало пусто > это ноль
   if s == "" then s = "0" end

   return s
end/CODE]      

Для чего? Важный нюанс (часто упускают) QUIK на все способен, иногда даёт:
* order_num = number
* потом в OnTrade → string
* иногда с ведущими нулями
.....?

Без нормализации это гарантированный рассинхрон (что теперь исправляет функция):
(v)   Нет расхождения типов ("123" vs 123)
(v)   Нет проблем с "000123"
А это значит, Нет “потерянных” трейдов! Стратегии получают свои сделки > позиция синхронизирована!

Возможно что то упустил проверяйте?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Ошибка создания заявки. [GW][332] "Нехватка средств по лимитам клиента.". Кто не получал данную ошибку от QUIK у того наверняка нет торгового скрипта.

MM (Money Manager) часто увязывают с RM (Risk Manager) не разделяя ответственность, но ведь RM отвечает только за критические состояния. В то время как MM отвечает за управление количеством. А ведь задача управления количеством напрямую связана с управлением капиталом и отвечают в сумме за рост этого капитала! В то время как RM за риск и минимальные убытки! И это ключевой момент, который часто путают в реальных системах.

Посмотрим на проблему и разложим по уровням и ответственностям, чтобы был понятен профессиональный контракт MM - CA - RM, и получен ответ на вопрос почему "текущая схема скверная"?
Для единства смыслов: "контрактный подход — это проектирование компонентов через формальные, однозначные интерфейсы (контракты), которые описывают входы, выходы, побочные эффекты, ошибки и ожидаемое поведение".

Применить профессиональный контрактный подход для MM/CA/RM - это значить снять неоднозначности и сделать систему предсказуемой и тестируемой. А главное решить задачу предотвращения гонки или повторного выставления ордеров. В такой постановке идея сводится к следующим постулатам:
 * RM не "контролирует лоты" — это зона ответственности MM.
 * RM — только аварийная защита, stop-loss, лимиты портфеля, стресс-сценарии.
 * MM отвечает за рост капитала через количество с учётом лимитов и риск-бюджета.

 Почему у меня было скверное управление?
1. Смешение зон ответственности. в старых версиях стратегии сами проверяли поток, капитал и выставляли target > EE и MM фактически дублировали функции.
2. RM и MM не разграничены. RM часто блокирует или разрешает ордер одновременно с MM > гонки и дублирование проверок.
3. Нет единого контракта. стратегии могут создавать интенты независимо от текущих лимитов CA > возникает [GW][332].

 Родилась схема управления капиталом. Схема ответственности и потоков капитала в стиле профессионального контрактного подхода, с выделением TS / MM / CA / EE (Execution Engine) / RM и местом GW[332].
1. TStrategy:
  * Генерирует сигнал > target.
  * Не контролирует лоты и не проверяет лимиты.
2. MM:
  * Получает сигнал от TS > запрашивает CA > решает allowed_qty.
  * Передаёт EE: только проверенное количество.
3. CA:
  * Проверяет все лимиты: инструмент, стратегия, портфель.
  * Возвращает allowed_qty + reason.
4. EE:
  * Получает allowed_qty от MM > выставляет ордер.
  * При reject / GW[332] > повторно обращается к CA / MM с backoff.
5. RM:
  * Контролирует критические состояния и аварийные лимиты.
  * Может отключить стратегию или весь портфель, если превышен stress limit.

Поток: TS > (signal/target) > MM > (check CA, allowed_qty) > EE > GW > PM > EE feedback > MM/TS
                              ^
                              RM мониторинг критических лимитов

* MM полностью управляет количеством, согласовывает с CA.
* RM только мониторинг и аварийные действия.
* EE выполняет FSM, orphan_trades, retry, TTL.
* TS сосредоточен на генерации сигналов, фильтров и target.

Осталось воплотить в код. Удачи!
свободные средства для срочного рынка на едином счете
 
"Интересно девки пляшут..." В торговых callback - ах QUIK вывел в лог флаг и вот что получаю:
Код
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.68 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.69 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.69 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.69 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.69 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.69 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.69 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.69 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.69 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.69 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.69 flags=0x40 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnTrade: SPBFUT NGJ6 qty=1 price=2.70 flags=0x24 brokerref=
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.68 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.68 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.68 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.68 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.68 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.68 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.68 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.68 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.68 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.68 flags=0x1E 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.69 flags=0x1C 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.70 flags=0x18 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.70 flags=0x1E 
2026-04-21 22:44:06 [INFO] [MAIN] OnOrder: SPBFUT NGJ6 qty=1 price=2.70 flags=0x1C 


И это еще не все, небольшая часть. Конечно понимаю, что есть служебные, но в таком количестве, зачем они конечному пользователю?
Возможно нужно фильтровать ответы по этому параметру, смущает то, что можно важную информацию потерять?
Посмотрел в документации ни чего, про то что трогать не нужно. А может есть  полезные из них для авто трейдинга? В общем вопросов больше чем ответов.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
VPM,  Вот еще что, на вскидку этот Ваш подход можно опробовать на CODEX от OPENAI. Мне кажется, там что - то подобное делается при создании навыков. Один агент и множество навыков сильно все упрощает. Тем более пока есть вариант бесплатный, можно пробовать. Навыки можно заимствовать от других пользователей. По крайней мере сильно смахивает на Вашу модель и при этом под силу одному разработчику.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
nikolz, То что Вы описываете сильно смахивает на работу фонда с бригадами специалистов из разных областей. Молчу уже про надежность такой распределенной системы, здесь все таки основной вопрос А ЗАЧЕМ? Для проведения экспериментов ну возможно любопытно? Но  я то рассуждаю о торговых программах доступных частному трейдеру. Где основное мерило успеха рост капитала, не получение прибыли а рост капитала. И все сразу становится на сои места.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Связка QUIK (QLua) + Московская биржа (MOEX) технически подходит для реализации такой архитектуры. Но  есть одно огромное НО - QLua не может быть ядром такой системы.
QLua можно использовать как транспортный шлюз (OrderExecutor), в то время как искусственный интеллект и логику выносят во внешнюю среду. И я с этим полностью согласен.
Писать нейросети и AI-агентов прямо в QUIK на Lua идея так себе. Lua в QUIK однопоточный, не имеет библиотек для работы с ИИ и быстро "захлебнется" от сложных вычислений.
Выносить вычисления во внешний контур (Python/С) не мой подход. В своем подходе HFT техники тяну по ряду причин, одна из которых быстрый тест. Вторая, низкая ликвидность на MOEX, привела к тому что рынок загнали в коридор (фондовый), плохо работают среднечастотные и долгосрочных стратегии. Смена парадигмы, от жесткого программирования правил к торговле на основе намерений (intent-based trading ) и так можно реализовать. Ведь задачу можно свести к модульности и независимости, где компоненты общаются через цели, а не прямые команды, это должно повышать адаптивность и защищать от ошибок. А математику упростить.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Да чуть не забыл. IntentStore — отдельный слой, буфер намерений, интентов (очередь, приоритеты). Тот самый третий не лишний!
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
«Кручу, верчу, запутать хочу»

Мой бег по кругу нашел себе новую проблематику зацикленность под общим названием Execution (Исполнение).
Или почему третий не всегда лишний. И это не из области "сообразить на троих", это когда соревнуются две команды и нужен объективный независимы судья. В нашем случае соревнования идут между потоками QUIK / Lua, а кто судья?

Что кручу, верчу. Архитектурный слой Исполнения отвечающей принципу разделения ответственности.

У меня сейчас выглядит так:
а) strategy:
 * считает alpha
 * говорит: "хочу позицию X"
б) PositionManager:
 * хранит истинную позицию (truth)
 * хранит цель (target)
 * дергает ExecutionEngine
с) ExecutionEngine
 * превращает target > ордера
 * управляет жизненным циклом (lifecycle)
д) OrderExecutor
 * гарантирует принцип - точно один раз (exact-once)
 * управляет заявками.
Это уже нормальный 4-уровневый стек выполнения. Оказалось что этого не достаточно.

Есть скрытая проблема такой архитектуры, PositionManager стал на уровень маршрутизации (routing layer), что означает > PositionManager = dispatcher. А это опасно.
Почему это проблема, PositionManager теперь: хранит truth, но также управляет поток выполнения (execution flow), а это уже смешение > состояние портфеля + оркестр выполнения. И архитектура начинает "ломаться".

# проблема №1 — двойной путь управления (control path) есть:
Path A. Strategy > PositionManager > ExecutionEngine
Path B (неявный будущий риск). Strategy > ExecutionEngine это почти гарантированный будущая ошибка.

Просмотр prop-desk стандартов дал однозначный ответ, как можно надежно выстраивать данную архитектуру. Правильная индустриальная модель (важно!) должна учитывать одну абстракцию, а именно УРОВЕНЬ НАМЕРЕНИЯ (критически недостающий элемент) текущей архитектуры.

Тогда новая правильная модель архитектуры будет содержать:

Strategy
  v
PositionManager
  v (creates intent)
ExecutionIntentStore
  v
ExecutionEngine
  v
OrderExecutor

Почему НУЖЕН ExecutionIntent чтоб не упереться в потолок! Без intent layer получаешь:
* логика выполнения размазана между модулями;
* PositionManager начинает расти;
* ExecutionEngine становится "умным монстром";
* состояния гонки между стратегиями.
Следовательно, PositionManager НЕ должен вызывать ExecutionEngine напрямую! И мой забег выходит на новый круг.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
TGB, Спасибо, идея понятна обязательно опробую у себя!
Коллбек OnTrade
 
Буквально в начале недели прочитал релиз от ВТБ, в котором приводилось отношение 3/4 счетов физических лиц <= 10 000 рублей! В свою очередь меня это сильно удивило. О каком пассивном доходе здесь может идти речь? Все съедят комиссии! У себя даже модель собрал под рабочим названием “жить на купоны + кредитка”. И принципиально модель нельзя путать с инвестиционной, кардинальные отличия.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
В моем нынешнем варианте (который пытаюсь довести "до ума") скорость цикла main делаю адаптивной к загрузке очереди.

Код
local qsize = get_queue_size(ctx.queue)
            if qsize > 10000 then sleep(1)
            elseif qsize > 1000 then sleep(5)
            elseif qsize > 100 then sleep(10)
            else sleep(20) end
       Но пока очередь не переполнялась то и выводов нет. Размер очереди задаю изначально. Но это так пока эксперименты?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Может я не все детали уловил, есть же вариант асинхронной (корутины) для  обработки таблиц таких загруженных, как таблицу обезличенных сделок?  А фильтровать параметры через SearchItems? Ну как вариант. Если много инструментов мне думается важны предельно допустимые нагрузки на QUIK? Можно все повесить. А скорость цикл main она просчитывается 1000 мс / (30 - 50 сделок). Можно как стандарт брать.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Что же это получается, 30 - 50 сделок в секунду с поиском их при помощи SearchItems в потоке QUIK, ну допустим в 10 раз быстрее чем сделает Lua. Здесь главная задача остается не перегружать основной поток. Так как я уже задумался про обработку таблицы всех сделок этим способом. То нужны критерии нагрузок?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Да Усек, "Функция SearchItems — это встроенный в QUIK «движок» быстрого поиска. Главная её фишка в том, что она перебирает строки таблицы на уровне C++, что в десятки раз быстрее, чем обычный цикл for в Lua."
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
А чем хуже тогда этот вариант?

Код
function main()
    local last_trade_count = getNumberOf("trades") -- Запоминаем кол-во сделок при старте
    
    while is_run do
        local current_count = getNumberOf("trades")
        
        if current_count > last_trade_count then
            -- Проходим по всем новым сделкам
            for i = last_trade_count, current_count - 1 do
                local trade = getItem("trades", i)
                message("Новая сделка (Pull): " .. tostring(trade.sec_code) .. " по цене " .. trade.price)
            end
            last_trade_count = current_count
        end
        
        sleep(30) -- Пауза  мл.секунд, чтобы не вешать процессор
    end
end
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
А можете не большой пример кода опроса показать, через  SearchItems? Что то у нас с ним  ни как отношения не сложатся. Уж больно мудрёная функция какая - то.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
nikolz,  Спасибо за демонстрации подходов, на мой взгляд нет большой надобности в наших задачах выстраивать какие - то изыски? У меня все просто для задачи  executor: FSM, event queue, orphan buffer, recovery, net-order support. Сейчас такой вариант:

Код
-- ============================================================
-- 1. Order State Machine (FSM)
-- ============================================================
local OrderState = {}
OrderState.__index = OrderState

function OrderState:new(trans_id, params)
    local o = {
        state = "NEW",          -- NEW, SENT, ACK, PARTIAL, FILLED, CANCEL_PENDING, CANCELLED, REJECTED
        trans_id = trans_id,
        order_num = nil,
        strategy = params.strategy,
        sec = params.sec,
        side = params.side,
        qty = params.qty,
        price = params.price,
        filled = 0,
        created_at = os.time(),
        last_update = os.time(),
        is_net = params.is_net or false,
    }
    setmetatable(o, self)
    return o
end

function OrderState:on_sent()
    self.state = "SENT"
    self.last_update = os.time()
end

function OrderState:on_ack(order_num)
    self.order_num = order_num
    self.state = "ACK"
    self.last_update = os.time()
end

function OrderState:on_trade(trade_qty)
    if self.state == "CANCELLED" then
        self.logger:warn("Trade after cancel, still processing")
    end
    -- обновление filled
    if self.filled >= self.qty then
        self.state = "FILLED"
    else
        if self.state ~= "CANCELLED" then
            self.state = "PARTIAL"
        end
    end
end

function OrderState:on_cancel()
    if self.state == "FILLED" then return end
    if self:is_active() then
        self.state = "CANCEL_PENDING"
    end
end

function OrderState:on_cancelled()
    self.state = "CANCELLED"
    self.last_update = os.time()
end

function OrderState:on_reject()
    self.state = "REJECTED"
    self.last_update = os.time()
end

function OrderState:on_timeout()
    if self:is_active() then
        self.state = "CANCELLED"
        self.last_update = os.time()
    end
end

function OrderState:is_active()
    return self.state == "SENT" or self.state == "ACK" or self.state == "PARTIAL"
end
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Nikolay,  Кажется уловил Вашу идею, все дело в буффере. Именно он опять возвращает в событийную модель через опрос + буффер, вместо callbacks + буффер?
И решаются вопросы тайминга?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Nikolay,  То что таблица trades это фактический журнал сделок, я понимаю.
Почему я акцентировал внимание. Я о той грани, что отделяет статику от динамики. В статике да Вы все правильно описали, согласен целиком, а в динамике — нет?

Расхождение возникает не в полноте истории данных, а в семантике доступа их получения, в моменте её доступности.

1) Мы получаем: МНОЖЕСТВО сделок (set)
2) Мы получаем: ПОТОК сделок (stream)
Смыслы для программирования можно свести к следущим:
  Подход 1. Pull (SearchItems)
 Подход 2: Push (OnTrade)
А это фундаментально разные модели.

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

Формально, SearchItems даёт полную историю, НО не гарантирует, что она уже полная в момент запроса?  Ну например гонка терминал / сервер (может быть?)
T0: сделка произошла на бирже
T1: мы взываем SearchItems
T2: QUIK обновил таблицу trades, мы НЕ увидели эту сделку.

В то время как OnTrade просто доставка события.
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Заглянул в материальную часть. То, что  по сути описал Nikolay,  - это  модель State-based FSM (pull + buffer), а не event-driven FSM. Нужно более детально разобрать отличие? Так как мой первоначальный замысел и реализация все таки крутится в парадигме event-driven FSM.

Предложенная модель:
1. Отправили транзакцию
2. Ждём появления order (любой источник)
3. Смотрим состояние order
4. При необходимости подтягиваем trades
5. Двигаем FSM
И главное, не важно, в каком порядке пришли данные!

Переформулирую принцип данной модели: "FSM НЕ должен зависеть от порядка событий !НО должен потреблять события как источник истины"?

Что смущает? Заявлено в подходе "можно просто прочитать таблицу сделок через SearchItems”  Когда делаешь: SearchItems("trades", ...)  получаешь текущее состояние таблицы НО НЕ полную историю изменений?

Что при этом теряешь:
1.  Не знаешь - уже учитывал этот trade или нет
2.  Дельту. было  fill = 30 стало fill = 50, не знаешь - это +20? или пересчёт? или дубликат?
3. Частичные исполнения в динамике. (Для FSM важно  PARTIAL > PARTIAL > FILLED, а snapshot даёт balance = X)

А что с подходом Event-driven (моя текущая)
+ точная история (trade_num)
+ идемпотентность
+ корректный partial fill

- нужно решать out-of-order?

Что не так?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Видимо Алиса не знакома с Теорией решения изобретательских задач  (ТРИЗ). Где базовая логика начинается с:   "Любая сложная задача - это Противоречие❗" :smile:
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Цитата
TGB написал:
Это массовая подача заявок с ограничением < 50 заявок в секунду? И до этого вы бы не додумались, если бы вы не прочитали про HFT?
А что это за ограничения? У брокера? Но даже на этой скорости исполнения заявок 1000 мс / 50 = 20 мс. нужно четко корректное исполнение. Что не так то?
Система принятия решений и/или Нечеткая логика(FuzzyLogic), Нечеткая логика или Система принятия решений в трейдинге
 
Nikolay,  У меня ломается система, пытаюсь установить причины и довести событийную модель "до ума". Возможно и перестарался с проблематикой надежности, но уже "дую на воду".  И почему бы не колбеки использовать? В любом случае основные проблемы: асинхронность прихода и их потеря установленны.  

А "Hybrid model: Event-driven (основа) + Snapshot reconciliation (страховка)", мне пока представляется наиболее правильной для использования в QUIK?
Система принятия решений и/или Нечеткая логика(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

Что не так делаю?
Страницы: 1 2 3 4 5 6 7 8 9 10 11 ... 30 След.
Наверх