575 lines
56 KiB
Markdown
575 lines
56 KiB
Markdown
# Changelog
|
|
|
|
## 2026-09-12 — этап 15 одиннадцатого аудита (fix audit-14)
|
|
Устранены остаточные расхождения одиннадцатого статического аудита
|
|
(Git HEAD 9349164): игнорирование отказа снятия checkpoint.marker в
|
|
основном экспорте, повторная выдача новой сессии каталога с частичным
|
|
остатком прерванного экспорта (только samples/events) и остаточная
|
|
принудительная перерисовка при клике по чужому объекту графика внутри
|
|
открытого измерительного окна.
|
|
Прежние 126 условий проходят; новая регрессия этапа 15 (SESS-03):
|
|
RequestLatencyTests PASS=127 FAIL=0 TOTAL=127,
|
|
сборка 4 exe 0 errors / 0 warnings.
|
|
|
|
- R15-B1 (P1): ExportRun проверяет результат FileDelete при инвалидации
|
|
checkpoint.marker (как ExportCheckpoint) — при отказе пара samples/events
|
|
НЕ открывается на перезапись, экспорт повторяется на таймере;
|
|
результатом удаления является false (MQL5 FileDelete [D1]).
|
|
- R15-B2 (P1): NewSessionId считает каталог занятым по ЛЮБОМУ известному
|
|
файлу отчёта сессии (SessionDirUsed: samples/events/schedule/deals/summary/
|
|
histogram/offset_signs/comparisons/market_windows/market_ticks/checks/
|
|
experiment_manifest), а не по трём служебным именам — частичный остаток
|
|
прерванного экспорта не маскируется новой сессией.
|
|
- R15-S1 (P2): клик по чужому объекту графика в OnChartEvent не вызывает
|
|
принудительную перерисовку внутри открытого окна измерения (тот же
|
|
безопасный режим, что в ветви занятого Start).
|
|
|
|
## 2026-09-12 — этап 14 десятого аудита (fix audit-13)
|
|
Устранены расхождения десятого статического аудита (Git HEAD 148e7a7):
|
|
повторное использование каталога сессии LOCAL_ONLY, действующий marker после
|
|
повреждения пары основных файлов экспортом и остаточная принудительная
|
|
перерисовка внутри отдельных открытых окон.
|
|
Прежние 123 условия проходят; новые регрессии этапа 14 (SESS-01, SESS-02,
|
|
WIN-02): RequestLatencyTests PASS=126 FAIL=0 TOTAL=126,
|
|
сборка 4 exe 0 errors / 0 warnings.
|
|
|
|
- R14-B1 (P1): идентификатор запуска отделён от измерительной шкалы —
|
|
NewSessionId выдаёт каталог по МОНОТОННОМУ счётчику сессий (курсор не
|
|
сбрасывается между вызовами) с проверкой существования каталога с данными
|
|
сессии (intents/manifest/checkpoint.marker): переустановка EA и повтор
|
|
после отказа первого INTENT получают НОВЫЙ session_id, перезапись прежнего
|
|
отчёта исключена; при исчерпании кандидатов — ошибка до записи/торговли.
|
|
- R14-B2 (P1): финальный marker публикуется ТОЛЬКО после полной записи и
|
|
контрольного чтения всей таблицы экспорта (единый PublishCheckpointMarker);
|
|
основной экспорт инвалидирует опубликованный marker ДО перезаписи пары
|
|
samples/events — обрыв между стадиями не оставляет действующий «успех»
|
|
над повреждённой парой.
|
|
- R14-S1 (P2): InMeasurementWindow учитывает и активный cleanup (не только
|
|
основную последовательность); отклонённый клик восстанавливает нажатый вид
|
|
кнопки БЕЗ принудительной перерисовки внутри открытого окна (ChartRedraw
|
|
откладывается до паузы).
|
|
|
|
## 2026-09-12 — этап 13 девятого аудита (fix audit-12)
|
|
Устранены остаточные расхождения девятого статического аудита (Git HEAD 37b3090):
|
|
сохранность незавершённого синтетического прогона, единый gate финализации,
|
|
изоляция окон повторной E3-сессии, проекция состояния панели из контроллера и
|
|
запрет принудительной перерисовки внутри измерительного окна.
|
|
Прежние 119 условий проходят; новые регрессии этапа 13 (START-03, START-04,
|
|
RESTART-01, CHECK-01): RequestLatencyTests PASS=123 FAIL=0 TOTAL=123,
|
|
сборка 4 exe 0 errors / 0 warnings.
|
|
|
|
- R13-B1 (P1): отказ SyntheticDispatch (durable-запись INTENT/SEND_RETURN) больше
|
|
НЕ стирает контекст незавершённой сессии — RunSynthetic финализирует её
|
|
(FINISHED + termination_reason SYNTHETIC_DURABLE_WRITE_FAILED), StartRun
|
|
возвращает true и направляет вызывающий код в экспорт частичного отчёта
|
|
(run_status=INCOMPLETE); резерв ДО T0 снимается (ReleaseReservation) — он не
|
|
является выполненным наблюдением; прерванная после T1 запись сохраняется как
|
|
DISPATCH_UNCERTAIN; ExportRun/ExportCheckpoint гарантируют каталог сессии
|
|
(FolderCreate) даже при отказе на первом INTENT.
|
|
- R13-B2 (P1): финализация — ЕДИНЫЙ проверяемый результат: FinalizeRun() требует
|
|
успешный финальный checkpoint (ExportCheckpoint(true) возвращает bool и
|
|
подтверждает marker контрольным чтением) И основной экспорт; повторяется именно
|
|
неуспешная стадия; FINISHED и разблокировка кнопки только после полного набора.
|
|
Иные завершения (DriveNext/EndMainCycle) используют ту же финализацию — marker
|
|
обязателен для любого пилота.
|
|
- R13-B3 (P1): ResetForRestart и StartRun очищают оконный контекст E3 прежней
|
|
сессии (m_windows/m_window_count, счётчики и недописанные оконные ссылки) —
|
|
старые окна не выгружаются в market_windows.csv новой сессии с её session_id.
|
|
- R13-S1 (P1): панель хранит НАМЕРЕННОЕ состояние кнопки (m_started) и
|
|
RestoreStartedState() восстанавливает нажатый вид после того, как OBJ_BUTTON
|
|
сам переключил OBJPROP_STATE при отклонённом клике; терминальный BLOCKED
|
|
отображается сразу (без зависимости от latch команды) и запрещает торговлю.
|
|
- R13-S2 (P1): SyncPanelPhase не вызывает ChartRedraw внутри открытого
|
|
измерительного окна (обновляется только текст панели; отрисовка — в паузе).
|
|
|
|
## 2026-09-12 — этап 12 восьмого аудита (fix audit-11)
|
|
Исправлены четыре группы функциональных расхождений восьмого статического аудита
|
|
(Git HEAD 9465fe6): повторный запуск с накопленными счётчиками/пропуском экспорта,
|
|
двойной старт одного клика (timer + OBJECT_CLICK), ложный FINISHED при ошибке
|
|
сохранения и зависимость финального checkpoint от 60-секундного порога.
|
|
Прежние 117 условий проходят; новые регрессии этапа 12 (RUNN-01, START-02):
|
|
RequestLatencyTests PASS=119 FAIL=0 TOTAL=119, сборка 4 exe 0 errors / 0 warnings.
|
|
|
|
- R11-B1 (P1): повторный запуск после финализации — независимые счётчики прогона
|
|
(CExperimentRunner::Init обнуляет MainDispatched/WarmupDispatched/CleanupDispatched/
|
|
PrecheckRejected/DispatchUncertain), ExtExportDone сбрасывается перед StartRun;
|
|
вторая сессия получает полный комплект отчётов (manifest/summary/market_ticks),
|
|
а не накопленные 400/40. Регрессии RUNN-01, START-02.
|
|
- R11-B2 (P1): один физический клик = один StartRun — независимый опрос
|
|
OBJPROP_STATE для запуска убран (источник истины — latch ExtStartPressed,
|
|
выставленный синхронно в OnChartEvent, потребляется таймером ровно один раз);
|
|
двойной клик и клики во время прогона игнорируются и не отменяют текущую сессию.
|
|
- R11-B3 (P1): ошибка экспорта не маскируется под FINISHED — пока отчёт не
|
|
сохранён, кнопка остаётся нажатой/заблокированной, повторный запуск запрещён,
|
|
статус EXPORT_FAILED с повторной попыткой на таймере; ResetForRestart разрешён
|
|
только после успешного экспорта.
|
|
- R11-S1: финальный checkpoint отделён от периодического — ExportCheckpoint(force)
|
|
пишет маркер всегда (короткий пилот не зависит от порога 60 с синтетического
|
|
времени); ошибка SyntheticDispatch (durable-запись) теперь возвращает
|
|
StartRun=false и состояние READY вместо ложного FINISHED с неотправленными резервами.
|
|
- Панель: SyncPanelPhase — статус фазы WARMUP/MAIN обновляется со счётчиками
|
|
диспетчеризации при смене фазы (лёгкая перерисовка только при изменении).
|
|
## 2026-09-12 — этап 10 седьмого аудита (fix audit-10)
|
|
Устранены четыре группы функциональных расхождений седьмого статического аудита
|
|
(Git HEAD a281c07): потеря ручного Start, неверное восстановление повторного
|
|
INTENT после отмены, раннее закрытие cleanup без ожидаемых DEAL-callback и
|
|
повреждённый формат архива тиков E3. Прежние 65 контрольных условий проходят;
|
|
новые регрессии этапа 10: RequestLatencyTests PASS=117 FAIL=0 TOTAL=117,
|
|
сборка 4 exe 0 errors / 0 warnings.
|
|
|
|
- R10-B1 (P1): ручной Start захватывается СИНХРОННО в OnChartEvent (latch
|
|
команды), а не опросом OBJPROP_STATE в OnTimer - клик больше не теряется.
|
|
Кнопка остаётся нажатой/заблокированной весь прогон (CLatencyPanel::SetStarted),
|
|
в Status выводятся фаза и итог; после финализации кнопка отпускается и работает
|
|
повторный запуск (CAppController::ResetForRestart FINISHED->READY, новая сессия)
|
|
либо ExpertRemove оператором. Терминальный BLOCKED также отпускает кнопку и
|
|
показывает причину. Регрессия START-01.
|
|
- R10-B2 (P1): CountUncertainDurableIntents сопоставляет INTENT_CANCELLED РОВНО
|
|
с одной попыткой того же sequence (хронологическая пара, массив cancel_used):
|
|
повторный INTENT после отмены без SEND_RETURN остаётся неопределённым
|
|
(n_dispatch_uncertain+1); прежняя отмена не маскирует новую попытку.
|
|
Регрессии DURA-09 (cancel->retry->crash => 1) и DURA-10
|
|
(cancel->retry->SEND_RETURN => 0).
|
|
- R10-B3 (P1): DriveCleanup принимает решение о закрытии коллекции cleanup по
|
|
СВЕЖЕЙ сверке (snapshot + SyncReconcile + CompletedCheck ДО условия закрытия)
|
|
по единой политике CompletedCheck: измерительные точки полны И полнота
|
|
DEAL-callback (T4/T5/callback_coverage_complete) подтверждена для операций с
|
|
ожидаемой сделкой (POSITION_CLOSE); PENDING_DELETE без сделки DEAL не ждёт;
|
|
неполноту закрывает grace. Вспомогательный предикат CleanupCollectionReady.
|
|
Регрессия CLN-02.
|
|
- R10-B4 (P1): FlushWindowTicks пишет market_ticks.csv с ЗАГОЛОВКОМ
|
|
(session_id,window_id,window_seq,time_msc,bid,ask,flags,volume) при
|
|
создании/пустом файле; разделитель строк - НАСТОЯЩИЙ CRLF (вместо литерального
|
|
текста \r\n); точность bid/ask - %.17g (полный round-trip double). Для каждой
|
|
сессии гарантируется наличие файла с заголовком (EnsureMarketTicksFile в
|
|
ExportRun); сбой записи - fail-closed. Статические форматтеры
|
|
MarketTickHeader/FormatMarketTickLine выделены для round-trip теста.
|
|
Регрессия WINDOW-02.
|
|
- R10-S1 (P1): SyntheticDispatch формирует СОГЛАСОВАННЫЙ объём DEAL-callback -
|
|
единственная сделка полного объёма плана (T4=T5); дубль deal с нулевым объёмом
|
|
не создаёт рассогласование callback_volume/coverage. Локальный прогон пишет
|
|
устойчивый журнал намерений (INTENT до T0, SEND_RETURN после T1) - intents.csv
|
|
сессии существует и CountUncertainDurableIntents работает и на LOCAL_ONLY
|
|
(критерии пилота: intents.csv, checkpoint.marker, market_ticks.csv).
|
|
- Тесты: TestAudit10Regressions (DURA-09, DURA-10, CLN-02, WINDOW-02, START-01).
|
|
|
|
|
|
## 2026-09-11 — этап 9 шестого аудита (fix audit-9)
|
|
|
|
Устранены функциональные блокеры R9-B1..B4 и существенные ограничения R9-S1..S4
|
|
по результатам шестого статического аудита (Git HEAD 4b16006). Повторные 48
|
|
контрольных условий аудита 8 на новом коде проходят; основные серии 5x100
|
|
разблокированы для пилота.
|
|
|
|
- R9-B1 (P1, E3): отказ по свежести контекста (code 8) БОЛЬШЕ не оставляет
|
|
неотправленный резерв в tracker — добавлен RequestTracker::ReleaseReservation:
|
|
удаляется запись без T0, повтор той же sequence слота проходит без дубликата
|
|
ключа (не code 6), фантомный MAIN в samples не экспортируется (n_attempted
|
|
растёт только по факту входа в транспорт). Откат выполняется и на pre-T0
|
|
отказах journal/durable-INTENT (code 61/63). Регрессия REL-01.
|
|
- R9-B2 (P1): DriveCleanup закрывает collection по ЕДИНОЙ политике
|
|
MeasurementPointsComplete (T2 и T3 по операции; REJECTED без ордера освобождает
|
|
T3) — T2 без T3 больше не завершает наблюдение cleanup раньше времени; неполноту
|
|
закрывает grace, ноль остатка не подменяет готовность измерения. Регрессия CLN-01.
|
|
- R9-B3 (P1): ConfirmDurableSendReturns теперь возвращает успех; все вызывающие
|
|
ветви (CompletedCheck, OnTimer, EndMainCycle, DriveCleanup) ПРЕРЫВАЮТСЯ при
|
|
сбое durable-flush и НЕ перезаписывают терминальный BLOCKED; SendCleanup имеет
|
|
собственный durability-gate (code 7) — служебная отправка запрещена при
|
|
нарушении сохранности; QueueDurableSendReturn при нехватке буфера — fail-closed
|
|
BLOCKED (а не молчаливый возврат). Регрессия DURA-07 (Directory-as-file отказ).
|
|
- R9-B4 (P1): checkpoint.marker инвалидируется ДО ЛЮБЫХ перезаписей данных
|
|
(samples.csv/events.csv), результат FileDelete проверяется; при неуспехе файлы
|
|
не трогаются и отправки блокируются (CheckpointState=false + BlockRun). Прерывание
|
|
на любой границе больше не оставляет ложный «успех» старого поколения.
|
|
- R9-S1 (P1): LoadSamples проверяет ВСЕ 68 имён заголовка (цикл hi<68): подмена
|
|
market_window_id/market_window_seq больше не принимается молча. Регрессия
|
|
READER-08 (good=1, bad=-1 code 32).
|
|
- R9-S2 (P1, E3): поставлена ПОВТОРНАЯ проверка свежести ВЫБРАННОГО контекста
|
|
(возраст наблюдения И возраст якоря окна относительно текущей котировки)
|
|
НЕПОСРЕДСТВЕННО перед T0 (после синхронных записей durable-INTENT). При застое
|
|
durable-INTENT явно отменяется (INTENT_CANCELLED), резерв откатывается (R9-B1),
|
|
слот ставится в очередь — без фантомного send. CountUncertainDurableIntents
|
|
учитывает INTENT_CANCELLED (пара = не неопределённость). Регрессия DURA-08.
|
|
- R9-S3 (P1, E3): Е3-окно не полагается больше на «границы+checksum+CopyTicksRange» —
|
|
сырые тики окна удерживаются В ПАМЯТИ (ComputeWindowRawTicks) и выгружаются в
|
|
market_ticks.csv в safe-фазе ПОСЛЕ закрытия окна (синхронная запись внутри
|
|
измерительной фазы по-прежнему запрещена R8-B3); checksum остаётся проверкой.
|
|
ExportRun дописывает оставшиеся тики при остановке. Формат описан в CSV_SCHEMA.
|
|
- R9-S4: новой E3-проверке присвоен отдельный ID REG-02 (не дублирует REG-01).
|
|
- R9-ДОП (NULL-сессия): guard'ы сессии (InitRun, AppendDurableIntent,
|
|
FlushPendingSendReturns, FlushWindowTicks) сравнивали m_session_id только с "" —
|
|
в MQL5 неинициализированная строка равна NULL, условие не срабатывало, и
|
|
durable-записи уходили в корневой tests\intents.csv вне каталога сессии; когда
|
|
этот путь занимал каталог (остаток Directory-инъекции DURA-07), flush падал с
|
|
code 66 «durable line open failed». Все 4 guard'а переведены на NULL||"":
|
|
сессия гарантированно создаётся в InitRun, каталог сессии используется по
|
|
назначению. Регрессия DURA-03 (before=2 flush=1 load=1 pend=0 err=0, sess
|
|
=tests_E1_S01_*).
|
|
|
|
Валидация: 4 exe 0 errors/0 warnings (MetaEditor 6191 avx2); RequestLatencyTests
|
|
PASS=112 FAIL=0 TOTAL=112 (5 новых проверок R9); EOL CRLF (bareLF=0 по 6 файлам);
|
|
CSV_SCHEMA.md обновлён (market_ticks.csv).
|
|
|
|
Ограничение тестирования, закрытое вручную: ветвь ReleaseReservation готова и
|
|
покрыта регрессией; ветви E3ContextStale по якорю окна и реально затянутого
|
|
durable-INTENT требуют живого терминала/диска — закрыты код-ревью и контрольными
|
|
пробами аудита (stale->refresh->retry->1 SEND).
|
|
|
|
## 2026-09-11 — этап 8 пятого аудита (fix audit-8)
|
|
|
|
Устранены функциональные блокеры R8-B1..B4 и существенные ограничения R8-S1/S2/S3
|
|
по результатам пятого статического аудита (Git HEAD 22ce0ff):
|
|
|
|
- R8-B1 (P0, E3): после терминальной остановки E3_WINDOW_CAPACITY_EXCEEDED /
|
|
E3_WINDOW_STORAGE_FAILED новая отправка недостижима: UpdateMarketRegime при
|
|
переполнении/ошибке хранения окна НЕ выводит режим (regime=UNKNOWN, m_last_regime
|
|
сбрасывается) и останавливает; DriveNext повторно проверяет состояние после
|
|
UpdateMarketRegime; в PrepareAndDispatch добавлен гейт code 7 перед транспортом
|
|
для FINISHED/BLOCKED. Регрессия REG-01.
|
|
- R8-B2 (P1): единая политика полноты измерительных точек CollectionCloseAllowed
|
|
(REQUEST T2; ORDER_ADD T3 по операции, кроме однозначного отказа без ордера)
|
|
применяется в CompletedCheck, пост-T6 ветви OnTimer и cleanup: одинаковое событие
|
|
«callback-покрытие полное» больше не закрывает коллекцию раньше T2/T3 (grace
|
|
закрывает позже). Регрессия T2-01.
|
|
- R8-B3 (P1): SEND_RETURN durable больше не пишется между T1 и обработкой
|
|
callbacks — факт возврата буферизуется (QueueDurableSendReturn) и дописывается
|
|
в safe-фазе после закрытия окна (FlushPendingSendReturns; вызовы после каждого
|
|
CloseCollection и в ExportRun); сбой дописывания — fail-closed (BLOCKED).
|
|
Регрессия DURA-03.
|
|
- R8-B4 (P1): CountUncertainDurableIntents — подтверждённые sequence собираются
|
|
динамически (без cap 256): парный журнал 440/1000 попыток даёт 0 неопределённых;
|
|
FileOpen INVALID_HANDLE различает отсутствие (0) и недоступность существующего
|
|
файла (sentinel ULONG_MAX); короткое чтение FileReadArray и сбой ArrayResize —
|
|
sentinel, а не частичный разбор; LoadDurableContent проверяет прочитанные байты.
|
|
Регрессии DURA-04/05/06.
|
|
- R8-S1 (P1): общий quote-aware счётчик логических записей CCsv::CountCsvRecords
|
|
использован и в ReadBackVerifyFile (multiline-экспорт не отвергает сам себя);
|
|
capacity в LoadSamples — число НАБЛЮДЕНИЙ (заголовок не расходует); ParseRow
|
|
отклоняет незакрытую кавычку; ParseCsvUlong проверяет диапазон 20 знаков;
|
|
LoadUtf8 проверяет число прочитанных байт (FileReadArray возвращает uint [D3]).
|
|
Регрессии READER-05/06/07.
|
|
- R8-S2 (P1, E3): в UpdateMarketRegime сначала фиксируется факт РЕАЛЬНО нового
|
|
тика (монотонный time_msc), затем проверяется возраст — polling-путь
|
|
восстанавливает контекст после паузы; перед T0 возраст контекста
|
|
перепроверяется (отказ code 8 без durable-INTENT); в samples добавлены
|
|
market_window_id/market_window_seq (68 колонок), в market_windows —
|
|
ticks_checksum (FNV-1a 64 по time_msc/bid/ask валидных тиков) — набор тиков
|
|
воспроизводится CopyTicksRange(from_msc,to_msc) и сверяется суммой; сырые тики
|
|
в send-пути на диск не пишутся (синхронная запись внутри измерения запрещена
|
|
по R8-B3). Регрессия WINDOW-01.
|
|
- R8-S3: FinalizeTransaction пишет ЕДИНОЕ exit_us один раз (без повторного
|
|
SetExitTime); инструментальная граница длины обработчика описана честно
|
|
(хвост финализации не включён); checkpoint.marker содержит поколение и
|
|
удаляется до перезаписи файлов.
|
|
|
|
Валидация: 4 exe 0 errors/0 warnings (MetaEditor 6191 avx2); RequestLatencyTests
|
|
PASS=107 FAIL=0 TOTAL=107 (10 новых проверок R8); EOL CRLF (bareLF=0 по 8 файлам);
|
|
CSV_SCHEMA.md обновлён (68 колонок samples, ticks_checksum, read-back, intents).
|
|
|
|
Ограничение, оставшееся осознанно: недоступность durable-журнала (sentinel
|
|
ULONG_MAX) не инъецируется в песочнице MQL5 (блокировка файла средствами языка
|
|
невозможна) — ветвь покрыта регрессией только до границы «существует/пуст», а
|
|
недоступные ветви — код-ревью и manual-тестом на реальном диске.
|
|
|
|
## 2026-09-11 — этап 7 четвёртого аудита (fix audit-7)
|
|
|
|
Блокирующие расхождения R7 устранены (демо-пилот и основные серии 5x100 — только
|
|
после повторного статического аудита; см. также следующий контрольный запуск):
|
|
|
|
- R7-B1 — устойчивый журнал намерений: `AppendDurableLine` пишет ровно n-1
|
|
полезных байт с индекса 0 (`FileWriteArray(handle,array,start,count)`;
|
|
`StringToCharArray` с WHOLE_ARRAY копирует завершающий ноль — прежний вызов
|
|
писал с последнего элемента и блокировал торговую отправку до T0). Настоящий
|
|
файловый round-trip INTENT/SEND_RETURN без NUL и отказ записи — DURA-01/02.
|
|
- R7-B2 — сборка callback-меток: раннее закрытие collection — только при
|
|
подтверждённой полноте ожидаемых точек T4/T5 (`callback_coverage_complete`), а
|
|
не по объёму из истории (`snap.coverage_complete`); снимок с
|
|
`history_scan_failed` полноту T5 по подмножеству тикетов НЕ повышает
|
|
(SyncReconcile); при доказанном покрытии после T6 коллекция закрывается в
|
|
OnTimer, запоздавшие в окне DEAL_ADD вносят исходные метки без пересчёта
|
|
финального исхода.
|
|
- R7-B3 — прогрев: квота — только по фактическим отправкам (`WarmupQuotaMet`);
|
|
расписание, исчерпанное с недобором фактических отправок (систематический
|
|
precheck-отказ), — терминальный `WARMUP_INSUFFICIENT_DATA` на ВСЕХ переходах
|
|
в MAIN (единый `ReturnToSchedule`), а не только в ветви DriveNext(WARMUP).
|
|
- R7-B4 — CSV-reader: деление на ЛОГИЧЕСКИЕ записи (кавычки/встроенные переводы
|
|
строк/CRLF), терминатор снимается один раз; пустые числовые ячейки сверяются с
|
|
`present_mask` (несоответствие — отказ code 40); `offset_signs_rebuilt` —
|
|
схема 10 колонок как онлайн; `histogram_rebuilt`/`offset_signs_rebuilt`
|
|
строят группы условий ИЗ ДАННЫХ + combined (одинаковые данные — одинаковая
|
|
схема таблиц онлайн/rebuild).
|
|
- R7-B5 — свежесть котировки: `NoteQuoteObserved(quote.time_msc)` обновляет время
|
|
наблюдения ТОЛЬКО при новом тике Рабочего символа (InpSymbol); повторное чтение
|
|
прежней котировки застой не маскирует; OnTick опрашивает рабочий символ, а не
|
|
символ графика; UpdateMarketRegime требует монотонного роста time_msc.
|
|
- R7-B6 — E4: обычный анализ принимает ТОЛЬКО допустимое экспериментальное
|
|
происхождение (по умолчанию `DEMO`; `SYNTHETIC` — отдельный синтетический
|
|
режим проверки отчёта, code 41); `data_origin` переносится во все производные
|
|
файлы; конфигурация СТРОК сверяется с manifest серии (code 42); в
|
|
`summary_rebuilt_e4.csv` добавлены показатели полноты (n_attempted/n_applicable/
|
|
отказы/пропуски/deadline) по сериям и pooled.
|
|
- R7-S1 — применимость метрик: неустановленный исход без сделки — отдельная
|
|
UNKNOWN-категория (не APPLICABLE/MISSING); доказанное отсутствие исполнения
|
|
(CANCELED_NO_FILL/EXPIRED_NO_FILL/PENDING_DELETED) — NOT_APPLICABLE, а не
|
|
«потеря callback»; CONFLICT/INTERRUPTED учитываются в summary ДО проверки
|
|
has_value (конфликт без числа не засчитывается MISSING).
|
|
- R7-S2 — comparisons: delta = B−A и относительное изменение (B−A)/A для
|
|
mean/median/p95 (ТЗ §7, стр.419); единая схема online и rebuild.
|
|
- R7-S3 — сохранность: cleanup-отправки тоже пишутся в intents.csv (INTENT до T0,
|
|
SEND_RETURN после T1); SEND_RETURN durable перенесён ВНЕ измеряемой фазы;
|
|
нечитаемость/повреждение durable-журнала даёт sentinel-неопределённость (не 0);
|
|
исчерпание протокола окон E3 — обязательная остановка
|
|
`E3_WINDOW_CAPACITY_EXCEEDED`.
|
|
- R7-S4 — единая метка выхода обработчика для events и metadata (одно exit_us);
|
|
переполнение реестра сделок блокирует дальнейшие отправки сразу (OnTransaction,
|
|
CheckIntegrity code 68), а не только итоговой RUN-DEAL-02; RegisterHistoryDeal
|
|
учитывает потери аналогично MarkDealAdd.
|
|
|
|
Регрессии: 97 проверок RequestLatencyTests (14 новых R7: DURA-01/02, WARM-02/03,
|
|
T5-03, DL-05, READER-03/04, CMP-02, EVAL-08/09/10, QUOTE-01, E4-03). Компиляция
|
|
4 exe 0 errors/0 warnings (MetaEditor 6191 avx2). EOL CRLF.
|
|
|
|
## 2026-09-11 — этап 6 третьего аудита (fix audit-6)
|
|
|
|
Блокирующие расхождения R6 устранены (полное соответствие ТЗ проверяется
|
|
демо-пилотом после контрольной сборки; основные серии 5x100 не запускать):
|
|
|
|
- R6-B1 — сквозная достоверность T5: вид сверки определяется ЯВНЫМ признаком
|
|
`ConfirmationSnapshot.light_snapshot`, а не числом сделок (световой снимок с
|
|
count>0 и обнулёнными тикетами больше не бьёт по нулевым тикетам в
|
|
SyncReconcile); первый реальный callback ПОСЛЕ history-регистрации учитывается
|
|
ровно один раз (deal_count/callback_volume не теряются); `RegisterHistoryDeal`
|
|
дополняет уже известную callback-сделку историческими атрибутами без потери
|
|
происхождения; history_volume наполняется только полным сканом; сверка полноты
|
|
callback-меток выполняется и после установки T6 (CheckTriggered/OnTimer) без
|
|
переписывания исхода/T6.
|
|
- R6-B2 — единая аналитическая семантика online/offline: rebuild-путь
|
|
восстанавливает RequestMetadata и считает метрики той же
|
|
`CRequestTracker::EvaluateMetric` (все категории/применимость/срок), а не
|
|
второй реализацией; WARMUP исключается одинаково; histogram/offset_signs/
|
|
comparisons/E4 используют ту же валидность; deadline-счётчики (n_deadline,
|
|
denominator, n_timestamp_missing_at_deadline) идентичны онлайну;
|
|
`source_set_id`/population/observation_unit одинаковы.
|
|
- R6-B3 — своевременность знаковой T2-T4 по ОБЕИМ точкам: max(T2,T4)<=deadline
|
|
(поздняя T2 при ранней T4 — LATE, и наоборот); `SetFinal` фиксирует
|
|
`deadline_exceeded` при поздней фактической T6 независимо от порядка callback
|
|
и таймера (sticky); общий флаг не переносится в пригодность остальных метрик.
|
|
- R6-B4 — планировщик: `MainComplete` — по фактическим отправкам и терминальным
|
|
состояниям слотов, а не high-watermark индекса (E3 не завершается при
|
|
неотправленной второй ветви); блоки формируются ДО перемешивания (каждый из 10
|
|
блоков: 10A+10B, 5Buy+5Sell на ветвь); прогрев учитывается по фактическим
|
|
отправкам (warmup-only жизненный цикл статусов, requeue/отказы), при
|
|
систематическом отказе подготовки запуск завершается неполным статусом
|
|
WARMUP_INSUFFICIENT_DATA.
|
|
- R6-B5 — согласование CompletionPolicy/контроллер: `PENDING_DELETED` не
|
|
подтверждается при `history_scan_failed`; доказанный исход без права установить
|
|
T6 (UNEXPECTED_ACTIVATION) сохраняется через `RecordOutcome`, а остаточная
|
|
позиция закрывается адресно; определённый REJECT без ордера трактуется как
|
|
известное состояние (нет экспозиции); cleanup UNKNOWN после grace завершается
|
|
конечным BLOCKED, а не бесконечным DRAINING.
|
|
- R6-B6 — сохранность: тяжёлый checkpoint выполняется ТОЛЬКО в безопасной фазе
|
|
(`CanCheckpoint`: нет активной записи и cleanup), результат записи проверяется
|
|
и при ошибке останавливает новые отправки (BLOCKED), маркер
|
|
`checkpoint.marker` пишется последним; добавлен устойчивый журнал намерений
|
|
`intents.csv` (INTENT до T0, SEND_RETURN после T1); INTENT без SEND_RETURN
|
|
учитывается как неопределённая отправка в manifest (CountUncertainDurableIntents).
|
|
- R6-B7 — E4: пять источников должны иметь manifest (отсутствие = отказ),
|
|
run_status=FINISHED и n_main_dispatched>=квоты; нормализованная конфигурация
|
|
(configuration_id) и символ равны МЕЖДУ всеми пятью сериями; каждая строка
|
|
принадлежит сессии серии; ключи sequence уникальны внутри файла.
|
|
|
|
Существенные (R6): S1 — CSV-reader проверяет полный заголовок из 66 имён,
|
|
числовые поля и уникальность sequence; S2 — монотонный возраст последнего
|
|
наблюдённого обновления котировки (застой рынка TimeCurrent не обнаруживает);
|
|
S3 — handler_exit_us и длительность снимаются ПОСЛЕ SetExitTime (включая поиск
|
|
события журнала); S4 — переполнение реестра сделок — явный отказ со счётчиком
|
|
потерь и проверкой RUN-DEAL-02.
|
|
|
|
Регрессии в RequestLatencyTests (TestAudit6Regressions): EVAL-05/06/07, DL-01..04,
|
|
OFF-01/02, E3-02, BLOCK-01, WARM-01, PDEL-04, PEND-04, READER-01/02, E4-02.
|
|
|
|
## 2026-09-11 — этап 5 повторного аудита (fix audit-5)
|
|
|
|
Блокирующие расхождения R5 (полное соответствие ТЗ не подтверждено до контрольной
|
|
сборки; торговые серии 5x100 не запускать):
|
|
|
|
- R5-B1 (P0) — автомат WARMUP->MAIN->CLEANUP->MAIN замкнут: EndMainCycle больше
|
|
не переводит в MAIN при `m_cleanup_in_flight` (единственный владелец перехода —
|
|
DriveCleanup после подтверждения нулевой остаточной экспозиции); прогрев строго
|
|
последователен (одна операция в работе, пауза); закрытие collection для cleanup
|
|
не зависит от наличия T6 (поздний REQUEST и grace закрывают коллекцию); раннее
|
|
закрытие в CompletedCheck ждёт ВСЕ ожидаемые точки (T2 всегда, T3 для операций
|
|
с ордерной точкой); `ReturnToSchedule()` выбирает WARMUP/MAIN по фазе расписания.
|
|
- R5-B2 — финализация/журнал/запись: intent проверяется ДО OrderSend* (переполнение
|
|
журнала -> BLOCKED, слот в очередь); FINISHED повторяет экспорт до первого успеха;
|
|
штатное завершение переводит контроллер в FINISHED (manifest run_status=FINISHED)
|
|
только без незавершённого cleanup; OnDeinit экспортирует журнал/записи; добавлен
|
|
периодический checkpoint (60 с) samples/events вне callbacks.
|
|
- R5-B3 — категория LATE по фактическому концу метрики против
|
|
`observation_deadline_us` (online и offline одинаково): ранние T4 остаются VALID
|
|
без T6; поздние T2/T6 — LATE независимо от порядка callbacks/таймера; флаг
|
|
`deadline_exceeded` остаётся информационным.
|
|
- R5-B4 — раздельные признаки: `callback_coverage_complete` (полнота локальных
|
|
DEAL_ADD callbacks) и `deal_coverage_complete` (торговый результат); T5-метрика
|
|
использует callback-покрытие; сделки из истории регистрируются в реестр
|
|
(deals.csv) с происхождением через `SyncRecoveredDeals`; результаты каждой
|
|
проверки переносятся в metadata (executed_volume/покрытия) — событийный full-fill
|
|
больше не остаётся с нулевым executed_volume.
|
|
- R5-B5 — RebuildReport: единая 41-колоночная схема summary_rebuilt (как онлайн);
|
|
устранены дублирующиеся ключи (c-loop 0..1 + combined); контрольное чтение — от
|
|
реально созданной таблицы (не константа 25); LoadSamples проверяет заголовок,
|
|
полную схему (66 колонок) и ёмкость — повреждённый набор отвергается; n=1
|
|
допустим (stddev пуст).
|
|
- R5-B6 — E3: возраст признаков на ОДНОЙ календарной шкале (TimeCurrent vs
|
|
quote.time_msc; GetMicrosecondCount не смешивается), контроль устаревания якоря
|
|
после CopyTicksRange; режим/окно/calibration_id закрепляются за записью при
|
|
отправке (не при late callback); калибратор добирает >=5 сессий (ёмкость 20000),
|
|
не сохраняет невалидный набор (INSUFFICIENT_DATA), выгружает период и исходные
|
|
окна (`<id>_windows.csv`); TryDispatchByRegime выбирает первую подходящую
|
|
возможность нужной ветви (слот другой ветви не блокирует).
|
|
- R5-B7 — RebuildE4: 5 РАЗНЫХ каталогов, уникальные source session_id, ровно
|
|
`expected_main` MAIN B-ASYNC на серию (вход `InpE4ExpectedMainPerSeries`), статус
|
|
исходных запусков из manifest (INCOMPLETE/BLOCKED отвергаются), единый символ;
|
|
warmup/PILOT/SYNTHETIC исключаются.
|
|
- R5-B8 — CompletionPolicy: FILLED/EXPIRED не подтверждают удаление
|
|
(PENDING_DELETED только CANCELED+нет активного+0 объёма; FILLED с нулевым объёмом —
|
|
противоречивый снимок; EXPIRED — не команда отмены); PARTIAL_CANCELED/EXPIRED
|
|
подтверждаются по отсутствию активного остатка (исторический неисполненный объём
|
|
не смешивается с активным); pending-create требует точного `expected_order_type`.
|
|
|
|
Существенные замечания R5-S1..S6:
|
|
|
|
- R5-S1 — универсальные построители расписания: малые чётные пилоты
|
|
(per_condition=4/10/40) дают валидные слоты без планов-пустышек; нечётные/нулевые
|
|
значения отвергаются в Init.
|
|
- R5-S2 — нулевые enum (ORDER_TYPE_BUY=0, ORDER_FILLING_FOK=0) пишутся как `0`
|
|
(признак `actual_known`); configuration_id переносится из Preflight в экспорт.
|
|
- R5-S3 — первичный журнал фиксирует SEND_START/SEND_RETURN MAIN с фактическими
|
|
данными (action/symbol/volume/type, retcode/request_id/order/deal).
|
|
- R5-S4 — CollectDealsByOrder с ограничением буфера и явным неполным исходом
|
|
(truncated -> history_scan_failed), бюджет сканирования не выдаётся за полноту.
|
|
- R5-S5 — группы исходов ALL/SUCCESS/REJECTED; n=1 допустим в summary (stddev пуст).
|
|
- R5-S6 — handler_exit_us штампуется в конце FinalizeTransaction (длительность
|
|
охватывает весь путь включая поиск записи журнала).
|
|
|
|
Регрессии в RequestLatencyTests.mq5: EVAL-01..04 (LATE по концу метрики),
|
|
T5-01/02 (callback vs trade coverage), PDEL-02/03, PART-01, PEND-03, PILOT-01,
|
|
ENUM-01, REBUILD-01 (сквозной tracker->samples->RebuildReport->73 строки),
|
|
E4-01 (повтор каталога отвергается). Сборка MetaEditor 6182 avx2: 0/0 для всех
|
|
4 exe (RequestLatencyLab, RequestLatencyTests, LatencyReport, MarketCalibration).
|
|
## 2026-09-10 — этап 4 повторного аудита (fix audit-4)
|
|
|
|
### Блокеры
|
|
- R4-B1: cleanup — в RequestPlan сохраняется полный фактический контракт (volume/type/filling/deviation/price-тикет/comment); потеря записи cleanup и неопределённое состояние DriveCleanup -> BLOCKED; остаточная экспозиция не разрешает следующий MAIN.
|
|
- R4-B2: событийная сверка — callback volume (лоты) конвертируется в units один раз на границе tracker/snapshot (CStateReader::LotsToUnits); regression UNITS-01..03.
|
|
- R4-B3: закрытие коллекции ждёт T2 (REQUEST) для всех операций; поздний REQUEST сохраняет метку после T6/закрытия; CORRELATION_LINK фиксирует deferred-привязку.
|
|
- R4-B4: MarketCalibration считает количество отдельных торговых сессий (уникальные даты валидных окон); generate->save->load->valid покрыт CAL-01/02.
|
|
- R4-B5: полные t.bid/t.ask (флаги не обнуляют вторую сторону); единое окно [anchor-60000, anchor-1]; anchor = quote.time_msc до T0; контроль возраста признаков (feature_max_age_ms); window/sequence/calibration/dataset трассировка.
|
|
- R4-B6: E4 — report-only workflow (LatencyReport InpE4Mode): ровно 5 E1 ASYNC datasets, проверка совместимости, pooled-статистика из 500 первичных записей + per-series таблица со ссылками на исходные session_id (без копирования samples).
|
|
- R4-B7: WAIT/precheck-reject возвращают слот в очередь (не расходуют квоту); DISPATCHED/квота E3 — только после фактического OrderSend/OrderSendAsync; недобор фактических send -> INSUFFICIENT_DATA (run_status=INCOMPLETE).
|
|
- R4-B8: samples.csv — пустые поля для отсутствующих значений; actual_type/actual_filling/request_price фактического запроса; SyncReconcile объёмов после полной сверки; T6 evidence (order state, объёмы, активный остаток, позиция); summary: исключение CLEANUP, outcome_group ALL/REJECTED, combined A+B, EvaluateMetric-семантика применимости; histogram без знаковой метрики; offset_signs.csv и comparisons.csv экспортируются; rebuilt-зеркало в ReportBuilder.
|
|
|
|
### Существенные
|
|
- R4-S1: pending-delete — отсутствие активного ордера только при LAB_READ_ABSENT_CONFIRMED.
|
|
- R4-S2: pending-create — подтверждение размещения со сверкой symbol/type/magic/volume/price ожидаемого контракта.
|
|
- R4-S3: initial/remaining_volume_units в снапшоте конвертируются в units.
|
|
- R4-S4: handler exit фиксируется в журнале и для unresolved (seq==0).
|
|
- R4-S5: StartRun проверяет init journal/tracker/runner; экспорт fail-closed (read-back участвует в статусе, повторная попытка); run_status=INCOMPLETE при stop_reason.
|
|
|
|
### Регрессии Tests (>50 проверок)
|
|
UNITS-01/02/03, COLL-03, CAL-01/02, VOLU-01, QUOTA-01/02, PEND-01/02, PDEL-01, CSV-03, HIST-02, CMP-01 (плюс предыдущие).
|
|
|
|
|
|
|
|
## 2026-09-10 — этап 3 повторного аудита (fix audit-3)
|
|
|
|
Устранение блокеров B1-B10 и существенных S1-S6 третьего аудита.
|
|
|
|
### Блокеры (10)
|
|
- B1: cleanup переведён в полноценную запись tracker с role=CLEANUP: отдельный
|
|
lifecycle (precheck -> reserve -> T0/T1 -> correlation -> T6 -> подтверждение
|
|
нулевой экспозиции -> пауза -> следующий MAIN); DriveCleanup в OnTimer;
|
|
однократный учёт dispatch; отказ/остаток -> BLOCKED (безопасность).
|
|
- B2: отложенная корреляция ранних ORDER_ADD/DEAL_ADD — буфер PushDeferred с
|
|
исходной callback-меткой; ReconcileDeferred после появления точного моста
|
|
заполняет T3/T4 исходными временами.
|
|
- B3: коллекция не закрывается до собранного ожидаемого REQUEST (T2) для
|
|
market; поздний REQUEST после T6 не теряет T2-T4.
|
|
- B4: 4754 = «ордер не найден» -> ABSENT_CONFIRMED; 4756 и пр. остаются
|
|
FAILED; no_active исключает FAILED; коды ошибок сохранены в snapshot.
|
|
- B5: событийная сверка адресная и короткая (light, объём из callback);
|
|
полный История-скан вынесен в таймер/DriveCleanup.
|
|
- B6: проверка bool HistorySelect и HistoryDealsTotal; history_scan_budget
|
|
вместо жёстких 100000; сбой выборки -> не «нет сделок».
|
|
- B7: однозначный финальный reject (IsFinalRejection) подключён к T6; неоднозн.
|
|
TIMEOUT/CONNECTION/LOCKED/ERROR не превращаются в reject.
|
|
- B8: E4 запрещён для торгового runtime (PREFLIGHT/StartRun); reuse=1 в
|
|
experiment_manifest (анализ 5 серий E1 без повторной торговли).
|
|
- B9: статусы PLANNED->INTENT_SAVED->DISPATCHED; PRECHECK_REJECTED/WAIT
|
|
отдельно; счётчик фактических вызовов растёт только после OrderSend*;
|
|
убран двойной MarkPrecheckRejected.
|
|
- B10: проверка результатов SaveUtf8 в ExportRun, EventSetMillisecondTimer,
|
|
integrity-блок при потере журнала (records_lost -> BLOCKED).
|
|
|
|
### Существенные (6)
|
|
- S1: фактическое deviation/comment из настроек в запросе; поля в RequestPlan.
|
|
- S2: рыночный контекст (bid/ask/spread/tick_time_msc) фиксируется при отправке
|
|
и экспортируется в samples.csv (+ actual_type/filling/deviation/comment).
|
|
- S3: пустые статистики summary при n<2 (пустые вместо нулей/stddev=0).
|
|
- S4: LatencyReport повторно строит и histogram_rebuilt.csv; experiment_id и
|
|
series_id заполняются из выборки.
|
|
- S5: калибровка E3 требует совпадения символа, >=5 отдельных торговых сессий
|
|
(trading_session_count); MarketCalibration считает число сессий.
|
|
- S6: market cleanup заполняет type_filling/deviation и проходит PreCheck.
|
|
|
|
## 1.00 (черновик, 2026-09-08)
|
|
|
|
Первая рабочая структура кода RequestLatencyLab по ТЗ (черновик).
|
|
|
|
### Добавлено
|
|
- Основной советник `RequestLatencyLab.mq5` с автоматом
|
|
IDLE→PREFLIGHT→READY→WARMUP→MAIN→DRAINING→EXPORTING→FINISHED и режимами
|
|
LOCAL_ONLY / PENDING_CREATE_DELETE / MARKET_ORDER.
|
|
- Модули `Include/RequestLatencyLab/*`: Models, Configuration, TimeSource,
|
|
Statistics, EventJournal, MarketRegime, StateReader, CompletionPolicy,
|
|
RequestTracker, ExperimentRunner, CsvStorage, ReportBuilder, LatencyPanel,
|
|
AppController.
|
|
- Legacy-модули (адаптация статьи 1): `Legacy/BenchmarkStatistics.mqh`,
|
|
`Legacy/TradeRequestTools.mqh`, `Legacy/LifecycleAdapter.mqh`.
|
|
- Исходники статьи 1 (SHA-256 совпадают с ТЗ) используются по ссылке из
|
|
соседнего каталога `mql5-execution-microstructure`; каталог `Dependencies`
|
|
исключён (снимки не копируются).
|
|
- Скрипты: `MarketCalibration.mq5`, `LatencyReport.mq5`.
|
|
- Автотесты: `Tests/RequestLatencyTests.mq5` (LOCAL_ONLY, пишет checks.csv).
|
|
- Документация: README, CHANGELOG, CSV_SCHEMA, Docs/DependencyChanges,
|
|
Docs/RequestLatencyLab_TZ_RU.md, dependencies.lock.json.
|
|
|
|
### Ключевые решения
|
|
- `LatencySample` сохранена без изменений (10 редакторских полей, порядок/типы
|
|
неизменны).
|
|
- T0–T6 по `GetMicrosecondCount`; только REQUEST задаёт `retcode` структуры;
|
|
код RETURN хранится в `send_retcode`.
|
|
- Единый последовательный протокол: один запрос в работе, пауза ≥1000 мс,
|
|
резервный таймер 20 мс, сроки [T0, T0+5000 мс] / +1000 мс.
|
|
- Севдофиксация конфигурации через `configuration_id` (без дат и случайности).
|
|
- Park–Miller (seed) + Fisher–Yates; прогрев на отдельном состоянии PRNG.
|
|
|
|
### Известные ограничения (следующие шаги)
|
|
- CLEANUP-записи в live-цикле журналируются событиями и счётчиком;
|
|
полная отдельная LatencySample-строка для CLEANUP — предмет пилота (ДЕМО).
|
|
- Реглом-гейтинг E3 (`TryDispatchByRegime`) реализован, но приоритетный
|
|
диспетчер MAIN использует последовательные слоты; E3-сбор подтверждается
|
|
пилотом.
|
|
- Проверки, требующие DEMO_PILOT / AFTER_PUBLICATION — NOT_RUN до проведения.
|
|
- Публикация на MQL5 Forge не выполнялась (см. Docs/RequestLatencyLab_TZ_RU.md §10).
|
|
Сборка зависит от абсолютного пути к соседнему каталогу mql5-execution-microstructure.
|
|
## 2026-09-10 — повторный аудит (fix audit-2)
|
|
- B1: детерминированный HistorySelect перед CollectDealsByOrder (StateReader).
|
|
- B2: неизвестный REQUEST больше не получает fallback-привязку (0 + unresolved).
|
|
- B3: collection_closed реально управляет cleanup: разделение T6 и закрытия, grace-период.
|
|
- B4: событийная адресная сверка T6 в OnTransaction (HISTORY_ADD/ORDER_DELETE/DEAL_ADD); таймер - watchdog.
|
|
- S5: E3 формально завершается INSUFFICIENT_DATA (лимит окна кампании InpE3CampaignLimitMin).
|
|
- S6: preflight проверяет чистоту символа (позиции/ордера).
|
|
- S7: привязка позиции через trans.position/DEAL_POSITION_ID вместо PositionGetTicket(0).
|
|
- S8: RUN-T6-01 проверяет completed=>T6; отсутствие T6 у incomplete не ошибка.
|
|
- S9: регрессии CORR-09, COLL-01/02, POS-01, UNRES-01; CORR-07 обновлён.
|