Нейросети в трейдинге: Долговременная память торговых сценариев (VLADriver-RAG)
Введение
Трейдер редко воспринимает рынок как совершенно новую ситуацию. Даже при беглом взгляде на график он сопоставляет происходящее с прошлым опытом: вспоминает выход из диапазона, неудачный разворот или ускорение тренда после коррекции. Такое сравнение не всегда формулируется словами, но заметно влияет на решение.
Один и тот же ценовой импульс действительно может означать разное. После длительного накопления он способен открыть новое движение. После уже состоявшегося роста тот же импульс может стать последним ускорением перед откатом. Формально свечи похожи, однако предыстория, положение внутри более длинного процесса и состояние открытой позиции требуют разных действий.
Нейросетевая модель обычно работает иначе. Она получает ограниченное окно баров, набор признаков, состояние счёта и параметры позиций. Этого достаточно для описания текущей сцены, но не всегда хватает, чтобы определить её место в более продолжительном рыночном сценарии.
Простое расширение входного окна не решает проблему: вместе с полезной историей растут шум и вычислительная нагрузка. Рекуррентные блоки, временные свёртки и механизмы внимания удерживают недавний контекст, но не позволяют адресно обратиться к эпизоду, завершившемуся несколько месяцев назад; буфер воспроизведения, как правило, влияет на веса при обучении и не предъявляется Актёру при выборе действия.
В результате прошлый опыт оказывается сжат в параметрах модели. Такое обобщение необходимо, однако оно стирает детали редких случаев. Сеть может усвоить общую закономерность, но не сохранить каждый необычный сценарий в форме, пригодной для последующего сравнения. Особенно остро это проявляется при смене режима, когда прежние связи уже ослабли, а новые ещё не стали устойчивыми.
Отсюда возникает практическая задача: дать торговой системе долговременную память, которая хранит завершённые эпизоды отдельно от параметров нейросети. При новом решении модель должна уметь найти близкий исторический случай и использовать его как дополнительный контекст.
Речь не идёт об архивировании баров или механическом копировании старых сделок. Похожие начальные условия могут привести к разным результатам. Меняются волатильность, ликвидность, направление старшего движения и состояние счёта. Поэтому полезная запись должна связывать исходную рыночную ситуацию, фактически исполненное действие и итог уже завершённой позиции.
Подобный принцип предложен авторами работы "VLADriver-RAG: Retrieval-Augmented Vision-Language-Action Models for Autonomous Driving". Исходный фреймворк решает задачу автономного вождения, а не трейдинга. Он дополняет параметрические знания VLA-модели внешней базой структурированных дорожных сценариев. Текущая сцена преобразуется в компактное представление, по нему извлекаются близкие исторические примеры, а найденный контекст участвует в построении новой траектории.
Для финансового рынка важен именно архитектурный принцип. Внешняя память не заменяет анализ текущего состояния и не выдаёт готовую команду. Она возвращает модели конкретный опыт, который иначе был бы растворён в весах. Однако буквальный перенос дорожной архитектуры невозможен: на рынке нет камер, полос движения и траектории автомобиля. Необходимо заново определить единицу сценария, состав результата и правила объединения записей.
Полная торговая реализация VLADriver-RAG включает энкодер сценариев, долговременное хранилище, индекс, поиск нескольких релевантных записей и передачу извлечённого контекста Актёру. Такой объём выходит за рамки одной статьи. Поэтому здесь решается более узкая, но обязательная задача: определить элементарную ячейку памяти и операции, на которых основан дальнейший retrieval.
Сначала рассмотрим устройство авторского фреймворка. Затем перейдём к рыночной адаптации и опишем четыре структуры данных для одного завершённого торгового факта: терминальный результат, завершённую запись, центроид действия и центроид сценария. В завершение разберём два OpenCL-примитива. RAGScore сравнивает новый эмбеддинг с памятью, а RAGNearestPair находит близкую пару центроидов для контролируемого уплотнения.
Таким образом, главный вопрос текущей статьи формулируется точнее: как превратить завершённый торговый сценарий в компактную запись, которую можно сравнивать, обобщать и хранить в памяти ограниченного размера? Ответ на него станет первым шагом к системе, способной использовать прошлый опыт непосредственно при формировании нового решения.
Архитектура VLADriver-RAG
Авторы VLADriver-RAG начинают с проблемы длинного хвоста. Большинство дорожных ситуаций повторяется часто, поэтому хорошо представлено в обучающей выборке. Опасные сочетания встречаются реже: частично перекрытая полоса, необычное расположение участников движения или конфликт нескольких ограничений. Параметрическая модель может знать отдельные элементы такой сцены, но не обязательно умеет надёжно действовать при их редком сочетании.
В обычной VLA-архитектуре прошлый опыт хранится в весах нейросети. Извлечь конкретный эпизод по запросу невозможно. RAG добавляет непараметрическую память, однако прямой поиск по изображениям создаёт две новые трудности. Высокоразмерные визуальные признаки требуют много памяти и вычислений при сравнении. Кроме того, внешне похожие кадры могут требовать противоположных действий: достаточно изменить сигнал светофора или положение одного активного участника.
Поэтому VLADriver-RAG переносит центр поиска с внешнего вида сцены на логику взаимодействий. Система не отказывается от изображения, но строит для памяти отдельное структурированное представление. На верхнем уровне фреймворк состоит из трёх компонентов: Visual-to-Scenario, Scenario-Aligned Embedding Model и VLA Backbone.
Модуль Visual-to-Scenario преобразует визуальные наблюдения в семантические графы. Scenario-Aligned Embedding Model сворачивает последовательность графов в компактный вектор и формирует пространство, в котором расстояние отражает сходство дорожной логики. VLA Backbone объединяет текущие визуальные признаки, навигационную инструкцию и найденные исторические примеры, после чего раздельно строит путь и скоростной профиль.
Первый этап начинается с Scenario Primitive. Для момента времени t авторы описывают его тройкой элементов, отношений и физических состояний. К элементам относятся собственный автомобиль, соседние транспортные средства, знаки, сигналы светофора и геометрия полос.
Список объектов сам по себе мало полезен для планирования, поэтому примитив содержит типизированные отношения. Rlead задаёт продольное предшествование. Ractive отмечает активное ограничение, непосредственно влияющее на манёвр. Rinert связывает сцену с пассивным контекстом, а Ron указывает, по какой полосе движется автомобиль.
Физические состояния добавляют координаты, размеры, ориентацию, скорость, торможение, идентификаторы полос, расстояния до объектов и состояния сигналов. Из этих данных строится эгоцентрический семантический граф Gt(N,E). Узлы представляют объекты, их атрибуты содержат физические параметры, а направленные рёбра кодируют отношения.
Эгоцентрическая форма сокращает задачу. Системе не требуется исчерпывающее описание всей дороги. Достаточно сохранить объекты и ограничения, влияющие на движение собственного автомобиля. Благодаря этому разные улицы могут считаться близкими, если в них совпадает логика манёвра. И наоборот, почти одинаковые кадры одного перекрёстка разойдутся, если изменился сигнал светофора или появился объект на предполагаемой траектории.
Здесь легко провести рыночную аналогию. Два графика могут иметь похожую форму свечей, но относиться к разным фазам движения. В одном случае импульс начинает тренд, в другом завершает его. Поэтому для полезной памяти требуется не поверхностное сходство, а представление значимых связей и контекста.
Один граф описывает только текущий срез. Для поиска авторы используют последовательность {G1, G2, …, Gt}. Она показывает, как менялась сцена во времени. Автомобиль перед перекрёстком может подъезжать, тормозить или уже снова ускоряться. Один кадр этих различий не раскрывает.
Второй компонент, Scenario-Aligned Embedding Model, преобразует графовую последовательность в вектор S. Сначала каждый временной срез обрабатывает реляционная графовая сеть R-GCN. Для разных типов рёбер используются отдельные обучаемые преобразования, поэтому влияние впереди идущего автомобиля не смешивается с влиянием знака или полосы.
После пространственной обработки признаки поступают в Transformer Encoder с многоголовым вниманием. Он связывает отдельные графы во времени и может распределять внимание между изменением скорости, поведением соседних машин и сменой ограничений. Затем Attention Pool и линейная проекция формируют вектор фиксированной размерности.
Компактный вектор нужен для быстрого поиска, но сжатие не должно уничтожить структуру сцены. Поэтому модель эмбеддингов построена как энкодер-декодер. Декодер восстанавливает графовые связи из S, а функция потерь сравнивает предсказанные и исходные множества рёбер по принципу пересечения и объединения. Этот критерий заставляет вектор сохранять значимые взаимодействия.
Хорошего восстановления всё ещё недостаточно. Автоэнкодер способен удержать информацию, но расположить сценарии в латентном пространстве так, что обычное расстояние между ними не будет отражать физическое сходство. Для поиска авторы добавляют согласование с Graph-DTW — метрикой для пространственно-временных графов.
Динамическое временное выравнивание учитывает, что похожие процессы могут проходить одинаковые фазы с разной скоростью. Один автомобиль начинает тормозить раньше, другой позже, но логика сценария остаётся близкой. Предварительно рассчитанное расстояние Graph-DTW используется как эталон: евклидово расстояние между латентными векторами должно отражать различия исходных графовых последовательностей.
Итоговая цель первого этапа объединяет восстановление и метрическое согласование. Первая часть сохраняет топологический смысл, вторая делает его пригодным для поиска. После обучения декодер больше не нужен в рабочем контуре. Исторические графы кодируются один раз и помещаются в векторную базу, а текущий граф преобразуется тем же энкодером в поисковый запрос.
Третий компонент, VLA Backbone, объединяет три потока данных. Первый несёт непосредственное визуальное наблюдение. Замороженный Vision Tower формирует высокоуровневые признаки, которые после проекции становятся визуальными токенами.
Второй поток отвечает за память. Параллельно визуальные признаки проходят через модуль восприятия с классификационной и регрессионной головами. Он выделяет категории объектов и их физические параметры, формирует текущий семантический граф и создаёт запрос к базе. Найденные сценарные примитивы проходят через MLP-проекцию и превращаются в токены исторического контекста.
Третий поток задаёт навигационную задачу. Несмотря на слово Language в названии VLA, авторы используют не развёрнутую естественную речь, а числовые целевые точки и скорость собственного автомобиля. Отдельные MLP преобразуют их в навигационные и скоростные токены.
Три последовательности объединяются без предварительного усреднения. Это сохраняет происхождение признаков и позволяет механизму внимания по-разному использовать текущую сцену, инструкцию и исторические примеры. Рассуждающий блок построен на основе LLaMA-подобного Transformer Decoder примерно с 50 миллионами параметров и обучается с нуля.
Траектория не генерируется как текст. В последовательность добавляются две группы обучаемых запросов. Path Queries собирают признаки для геометрии будущего пути. Speed Queries отвечают за скорость прохождения этого пути. Через self-attention обе группы обращаются ко всему мультимодальному контексту, но сохраняют специализацию.
После рассуждающего блока две лёгкие MLP-головы формируют выходы. Path Head предсказывает путевые точки в представлении с высоты птичьего полёта. Speed Head строит последовательность целевых скоростей. Разделение важно: одна и та же геометрия манёвра может выполняться с разной скоростью, а одинаковый скоростной режим — сопровождать разные траектории.
Обучение проходит в три этапа. Сначала модель эмбеддингов оптимизируется по восстановлению графов и согласованию с Graph-DTW. Затем её фиксируют и обучают модуль восприятия: для категорий применяется Focal Loss, для физических параметров — Smooth L1 Loss. На третьем этапе вся политика планирования настраивается по ошибкам пути и скорости.
В опубликованной конфигурации база содержит 800 000 сценарных примитивов, а для каждого запроса выбираются десять исторических примеров. В блоке рассуждения используются 20 запросов пути, 10 запросов скорости и восемь голов внимания. Эти числа относятся к конкретному эксперименту, но показывают общий принцип: большая база остаётся снаружи, а в планировщик поступает лишь небольшой релевантный контекст.
Важно правильно понимать статус памяти. В авторской работе база строится заранее из экспертных дорожных сценариев. Она не является рекуррентным состоянием. В опубликованной версии механизм непрерывного обновления базы во время движения не реализован; авторы относят его к дальнейшему развитию.
Найденный сценарий также не служит готовой траекторией для копирования. Он становится частью контекста, тогда как планировщик продолжает видеть текущую сцену и навигационную цель. Новый путь синтезируется заново. Именно это отличает VLADriver-RAG от таблицы шаблонов.
Для торговой адаптации мы сохраняем три идеи: отделяем внешнюю память от параметров модели, ищем по содержательному представлению сценария и используем найденный опыт как контекст, а не как команду. Но само устройство записи будет другим. Вместо дорожного графа нам нужны рыночный эмбеддинг, исполненное действие и фактический результат завершённой позиции. К их организации и перейдём далее.

Реализация средствами MQL5
Полная торговая архитектура включает подготовку эмбеддингов, менеджер памяти, индекс, выбор релевантных сценариев и интеграцию с Актёром. Реализовать весь контур в одной статье без потери ясности невозможно. Поэтому начнём с минимального объекта — одной сценарной ячейки и правил её обновления.
Логика отдельной записи выглядит так: исходная рыночная ситуация преобразуется в ScenarioEmbedding, затем фиксируется фактически исполненное действие. После закрытия позиции вычисляется терминальный результат, и только тогда появляется завершённая запись. Пока позиция открыта, её текущая прибыль или просадка ещё не являются устойчивым историческим фактом.
Особенно важно сохранять именно исполненное действие. Выход Актёра, отправленная заявка и возникшая позиция могут различаться из-за маржинальных ограничений, допустимой дистанции защитных уровней, цены или частичного исполнения. Память не должна обучаться на операции, которой фактически не было.
Итоговый путь можно записать кратко: рыночная ситуация → ScenarioEmbedding → исполненное действие → закрытие позиции → Terminal outcome → Completed record. Начнём с терминального результата.
struct SRAGTerminalOutcome { float relative_return; float max_drawdown; float costs; float risk_usage; float duration; float reward; };
Структура SRAGTerminalOutcome хранит нормированную статистику завершённого сценария. Поле relative_return описывает относительный финансовый результат, max_drawdown — максимальное ухудшение внутри позиции, costs — торговые издержки, risk_usage — фактически использованный риск, а duration — продолжительность в единой шкале. Поле reward сводит эти характеристики к целевой награде торговой системы.
Нормирование не позволяет памяти привязаться к конкретному депозиту, абсолютному лоту или таймфрейму. Правило может опираться на капитал, выделенный риск или заданный горизонт, но оно должно оставаться одинаковым для всех записей.
Поле reward нельзя смешивать с оценкой Критика. Критик прогнозирует ожидаемую ценность до завершения позиции. SRAGTerminalOutcome фиксирует то, что произошло в действительности. Память строится по фактическому отчёту, а не по прежнему ожиданию модели.
struct SRAGCompletedRecord { float scenario_embedding[]; float action[]; SRAGTerminalOutcome terminal; };
SRAGCompletedRecord связывает три части одного завершённого наблюдения: эмбеддинг исходной ситуации, нормированное исполненное действие и терминальную статистику. Перед сохранением scenario_embedding проверяется на размерность, конечные значения и ненулевую норму, после чего применяется L2-нормирование. Компоненты action масштабируются отдельно, чтобы объём позиции или расстояние до защитного уровня не подавляли остальные координаты.
Завершённая запись ещё не является ячейкой памяти. Это материал, который нужно присоединить к существующей группе либо использовать для создания новой. Такие факты сначала накапливаются на стороне основной программы и не меняют снимок центроидов, доступный торговому контуру. Пока память перестраивается, Актёр должен читать целостную опубликованную версию.
struct SRAGActionCentroid { bool used; uint scenario_id; ulong hit_count; float mean_reward; float centroid[]; SRAGTerminalOutcome mean_terminal; };
Похожие действия внутри одного рыночного сценария объединяются в SRAGActionCentroid. Поле used отмечает занятую позицию массива, scenario_id связывает действие с родительской ячейкой, а hit_count показывает число наблюдений. Массив centroid хранит среднее действие, mean_reward — среднюю награду, mean_terminal — усреднённую полную статистику результата.
Дублирование mean_reward и mean_terminal.reward намеренно: первый скаляр удобен для ранжирования, второй остаётся частью полного терминального описания. Оба значения обновляются из одного источника.
Массив действий имеет только локальный смысл. Одинаковый индекс в разных сценарных ячейках не обозначает один класс поведения. Например, ActionCentroid[3] одного сценария может описывать удержание позиции, а того же индекса другого — частичное закрытие. Сравнивать нужно сами векторы действий, а не их места в массивах.
struct SRAGScenarioCentroid { bool used; uint scenario_id; ulong hit_count; float centroid[]; SRAGActionCentroid actions[]; };
SRAGScenarioCentroid образует верхний уровень элементарной ячейки. Его centroid — L2-нормированный центр близких ScenarioEmbedding, а actions содержит только действия, наблюдавшиеся в рамках этого сценария. Тем самым память хранит не глобальную частоту команд, а условную связь между рыночной ситуацией и поведением.
Счётчики дают простой инвариант: если каждая завершённая запись относится ровно к одному действию, то ScenarioHitCount = ∑ ActionHitCount. Нарушение равенства указывает на двойное добавление, некорректное удаление или ошибку консолидации.
Новый CompletedRecord обрабатывается в три этапа. Если близки и сценарий, и одно из его действий, оба центроида пересчитываются с весом по числу наблюдений. Вместе с ними обновляются средняя награда, терминальная статистика и счётчики.
Если рыночный сценарий близок, но действие заметно отличается, родительская ячейка сохраняется, а в её локальном массиве создаётся новый ActionCentroid. Принудительное усреднение разных решений могло бы породить центр, которому не соответствует ни одна реально исполненная операция.
Если сам рыночный эмбеддинг не проходит порог близости, создаётся новый SRAGScenarioCentroid с одним действием и единичными счётчиками. Полная маршрутизация по массиву ячеек будет рассмотрена далее; сейчас достаточно определить эти три исхода.
На стороне MQL5 структуры удобно хранить иерархически. Для OpenCL они преобразуются в плоские буферы одинаковой размерности. Перед публикацией проверяются флаги used, счётчики, идентификаторы родителей, конечность координат и ненулевая норма сценарных центров.
Первый GPU-примитив выполняет чтение памяти. RAGScore запускает отдельный рабочий поток для каждого сценарного центроида и рассчитывает косинусную близость с текущим запросом.
__kernel void RAGScore(__global const float *embedding, __global const float *centroids, __global const float *used, __global float *scores, const int scenario_count, const int embedding_dimension) { const int scenario=get_global_id(0); if(scenario>=scenario_count || embedding_dimension<=0) return;
Индекс из get_global_id(0) определяет ячейку. Потоки за пределами фактического количества сценариев завершаются. Незанятые позиции получают служебный результат MIN_VALUE, чтобы не участвовать в выборе максимума.
if(used[scenario]<=0.5f) { scores[scenario]=MIN_VALUE; return; }
Основной цикл одновременно накапливает скалярное произведение и квадраты норм. IsNaNOrInf заменяет повреждённую координату нулём. Это последняя защита; корректность снимка всё равно должна проверяться до запуска ядра.
float dot=0.0f, left=0.0f, right=0.0f; for(int d=0;d<embedding_dimension;d++) { float a=IsNaNOrInf(embedding[d],0.0f); float b=IsNaNOrInf(centroids[scenario*embedding_dimension+d],0.0f); dot+=a*b; left+=a*a; right+=b*b; }
Если обе нормы ненулевые, ядро возвращает косинусную близость. Для заранее нормированных векторов достаточно было бы скалярного произведения, но явный расчёт норм устойчивее к численному дрейфу.
scores[scenario]=(left>1.0e-12f && right>1.0e-12f ? dot/sqrt(left*right) : MIN_VALUE); }
Результатом запуска становится массив оценок по всем занятым ячейкам. Сортировка и глобальный Top-K здесь не рассматриваются. На первом этапе достаточно найти лучший допустимый сценарий и сравнить его оценку с порогом.
Второй примитив нужен для памяти ограниченного размера. Простое удаление старой записи опасно: редкий режим может вернуться, а возраст не определяет полезность опыта. Более аккуратный способ — объединить два ближайших центра и освободить одну позицию.
RAGNearestPair работает с ограниченным набором кандидатов, поскольку число пар растёт как N(N−1)/2. На уровне действий набором служит локальный массив одной сценарной ячейки. На уровне сценариев ядро применяется к заранее отобранной группе кандидатов.
__kernel void RAGNearestPair(__global const float *centroids, __global const float *used, __global float4 *result, const int candidate_count, const int dimension, const int batch_count) { const int lane=get_local_id(0); const int batch=get_group_id(0); const int lanes=get_local_size(0); __local float4 best[LOCAL_ARRAY_SIZE];
Каждая рабочая группа обрабатывает один независимый набор. Номер batch задаёт его начало в плоском буфере. Служебная функция RAGNearestPairIndex отображает линейный номер пары в индексы left и right, поэтому двумерная матрица расстояний не требуется.
float4 current=(float4)(MAXFLOAT,-1.0f,-1.0f,0.0f); if(candidate_count>1 && dimension>0 && batch>=0 && batch<batch_count && lanes>0 && lanes<=LOCAL_ARRAY_SIZE) { // candidate_count<=65536: divide the even factor before multiplying so // the documented maximum (2,147,450,880 pairs) stays in signed int. const int pairs=((candidate_count&1)==0 ? (candidate_count/2)*(candidate_count-1) : candidate_count*((candidate_count-1)/2)); const int base=batch*candidate_count; for(int pair=lane;pair<pairs;pair+=lanes) { int left=-1,right=-1; RAGNearestPairIndex(pair,candidate_count,&left,&right); if(left<0 || right<0 || used[base+left]<=0.5f || used[base+right]<=0.5f) continue;
Пары распределяются между потоками с шагом, равным размеру локальной группы. Элементы с выключенным флагом used пропускаются. Для каждой допустимой пары рассчитывается квадрат евклидова расстояния.
float distance=0.0f; const int lbase=(base+left)*dimension; const int rbase=(base+right)*dimension; for(int d=0;d<dimension;d++) { const float delta=IsNaNOrInf(centroids[lbase+d]-centroids[rbase+d],MAXFLOAT); volatile float squared=delta*delta; distance=distance+squared; }
Квадратный корень не нужен: он не меняет порядок кандидатов. Для L2-нормированных сценарных центров минимальное евклидово расстояние эквивалентно максимальной косинусной близости. Для действий та же операция корректна только после согласованного масштабирования компонентов.
Кандидат упаковывается в float4: расстояние, левый индекс, правый индекс и признак валидности.
const float4 candidate=(float4)(IsNaNOrInf(distance,MAXFLOAT),(float)left,(float)right,1.0f);
Функция RAGNearestBefore сначала сравнивает валидность, затем расстояние и, при равенстве, индексы. Последнее правило делает выбор детерминированным.
if(RAGNearestBefore(candidate,current))
current=candidate;
}
}
Лучший локальный результат каждого потока помещается в общую память рабочей группы.
best[lane]=current; BarrierLoc;
После барьера выполняется редукция. На каждом шаге число кандидатов уменьшается вдвое, а нулевой поток записывает итоговую пару.
for(int stride=lanes>>1;stride>0;stride>>=1) { if(lane<stride && RAGNearestBefore(best[lane+stride],best[lane])) best[lane]=best[lane+stride]; BarrierLoc; } if(lane==0 && batch>=0 && batch<batch_count) result[batch]=best[0]; }
Само объединение выполняется после выбора пары. Новый сценарный центр рассчитывается как нормированная сумма C1 ×count1 + C2 ×count2. Для действий по тем же весам пересчитываются вектор, средняя награда и все поля терминальной статистики.
На уровне сценариев нельзя объединять дочерние действия по одинаковым индексам. Их локальные массивы сначала соединяются, после чего близость определяется по содержимому центроидов. Это следует из уже зафиксированного правила: индекс действия не имеет глобального семантического значения.
Таким образом, текущая реализация задаёт две фундаментальные операции. RAGScore помогает найти подходящую ячейку для нового завершённого факта. RAGNearestPair освобождает место с минимальной локальной потерей опыта. Полный менеджер памяти, публикация снимков и выбор нескольких извлечённых сценариев остаются задачей следующего этапа.
Заключение
В начале статьи была поставлена практическая задача: сохранить завершённый торговый опыт так, чтобы модель могла позднее сравнить его с новой рыночной ситуацией. Обычное входное окно, краткосрочная память и веса нейросети не дают прямого доступа к конкретному далёкому эпизоду.
Авторский VLADriver-RAG показывает общий способ решения. Дорожная сцена переводится из пикселей в последовательность семантических графов, модель эмбеддингов согласует латентное расстояние с Graph-DTW, а найденные исторические примеры поступают в VLA-планировщик вместе с текущим наблюдением. Память дополняет решение, но не подменяет его готовым шаблоном.
В рыночной реализации мы выполнили первый обязательный шаг. SRAGCompletedRecord связывает эмбеддинг исходной ситуации, фактически исполненное действие и статистику завершённой позиции. Терминальный результат отделён от оценки Критика: в память попадает реализованный факт, а не прежний прогноз ценности.
Завершённые записи обобщаются в двухуровневой ячейке. SRAGScenarioCentroid представляет группу похожих рыночных состояний, а локальные SRAGActionCentroid сохраняют наблюдавшиеся в ней варианты поведения, их частоту, среднюю награду и терминальные характеристики. Три правила обновления охватывают известный сценарий с известным действием, известный сценарий с новым действием и полностью новую рыночную ситуацию.
Два OpenCL-ядра обеспечивают базовые операции над памятью. RAGScore параллельно оценивает близость запроса к сценарным центрам. RAGNearestPair выбирает пару для консолидации, взвешенной по числу наблюдений, и позволяет удерживать ограниченный размер хранилища.
Тем самым поставленная задача решена на уровне элементарной ячейки: завершённый торговый сценарий получил компактное, сравнимое и управляемое представление. Это ещё не полный RAG-конвейер и не доказательство улучшения торгового результата. Но теперь дальнейший retrieval будет работать не с неопределённым архивом сделок, а с формально заданной памятью.
В следующей статье отдельные ячейки предстоит объединить в менеджер хранилища, определить границу публикации неизменяемого снимка и организовать выбор релевантных сценариев для торговой модели.
Ссылки
- VLADriver-RAG: Retrieval-Augmented Vision-Language-Action Models for Autonomous Driving
- Другие статьи серии
Программы, используемые в статье
| # | Имя | Тип | Описание |
|---|---|---|---|
| 1 | Study.mq5 | Советник | Советник офлайн-обучения моделей |
| 2 | StudyOnline.mq5 | Советник | Советник онлайн-обучения моделей |
| 3 | StudyForecast.mq5 | Советник | Советник офлайн-обучения Market Encoder |
| 4 | Test.mq5 | Советник | Советник для тестирования модели |
| 5 | Trajectory.mqh | Библиотека класса | Структура описания состояния системы и архитектуры моделей |
| 6 | NeuroNet.mqh | Библиотека класса | Библиотека классов для создания нейронной сети |
| 7 | NeuroNet.cl | Библиотека | Библиотека кода OpenCL‑программы |
Проект представлен на forge.mql5.io/dng.
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Автоматизация торговых стратегий на MQL5 (Часть 39): Стратегия статистического возврата к среднему с доверительными интервалами и информационной панелью
От начального до среднего уровня: Очереди, списки и деревья (III)
Создание торговых систем с искусственным интеллектом на MQL5 (Часть 4): Преодоление ограничений многострочного ввода, сохранение чатов между сеансами и генерация торговых сигналов
Автоматизация торговых стратегий на MQL5 (Часть 38): Торговля по скрытым дивергенциям RSI с фильтрами угла наклона
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования