Машинное обучение и Data Science (Часть 41): YOLOv8v для поиска паттернов на рынках Forex и акций
Содержание
- Введение
- Что такое YOLOv8?
- Получение графических паттернов из MetaTrader 5
- Использование YOLOv8 для поиска паттернов
- Предвзятость, риски и ограничения YOLOv8
- Поиск графических паттернов в MetaTrader 5 с помощью YOLOv8
- Заключение
Введение
Выявление паттернов на финансовых рынках — сложная задача для моделей машинного обучения и искусственного интеллекта. Как бы легко это ни казалось нам, людям, машине требуется приложить определенные усилия, чтобы обнаружить и интерпретировать эти паттерны, просто потому что, в отличие от табличных данных, которые обычно используются в торговле, поиск паттернов распространяется и на двумерные изображения, которые обычно хранятся в форматах .png, .jpg и т. д.
Существует огромное количество трейдеров со стратегиями, основанными на анализе ценового движения (price action) и конкретных графических паттернах на рынках, таких как:
- Восходящая и нисходящая лестница
- Восходящий треугольник
- Нисходящий треугольник
- Симметричный треугольник
- Флаг
- Клин
- Двойная вершина
- Двойное дно
- Голова и плечи
- Скругленная вершина или дно
- Чашка с ручкой
- и многие другие.
Когда речь заходит о программировании, паттерны, связанные со свечными моделями (candlestick patterns) и реакциями индикаторов, которые можно найти без сложных строк кода, существенно отличаются от перечисленных выше графических паттернов, которые значительно более сложные.
Для определения даже простого паттерна, например W-дно, потребуется сложный, хорошо написанный и оптимизированный код. Так почему бы не попытаться справиться с этой задачей с помощью ИИ?
Чтобы решить эту проблему с использованием искусственного интеллекта (AI), в данной статье мы рассмотрим весьма интересную модель под названием YOLOv8, с которой я познакомился на сайте huggingface.co.
Эта модель помогает обнаруживать графические паттерны на изображениях и графиках с достаточно высокой точностью.
Для понимания содержания данной статьи требуется базовое понимание машинного обучения и языка программирования Python.
Что такое YOLOv8?
Согласно документации,
YOLOv8s — это модель обнаружения объектов, основанная на фреймворке YOLO (You Only Look Once). Данная модель предназначена для определения различных графических паттернов в режиме реального времени на основе данных о биржевых сделках, полученных с экрана компьютера.
Модель помогает трейдерам и инвесторам, автоматизируя анализ графических паттернов и предоставляя своевременные данные для принятия обоснованных решений.
Модель была дообучена на разнообразном наборе данных и демонстрирует высокую точность при поиске и классификации паттернов фондового рынка в условиях реальной торговли.
На текущий момент модель способна точно распознавать несколько паттернов, включая:
Голова и плечи
Краткое описание паттерна
Данный паттерн указывает на возможный разворот рынка.
Считается, что три последовательности вершин и впадин, когда при этом средний пик выше остальных, свидетельствуют о том, что цена акции начнет снижаться.
Линия шеи (neckline) представляет собой уровень, на котором медвежьи трейдеры начинают продажи. Подробнее.
Перевернутая голова и плечи
Это противоположный вариант паттерна "голова и плечи"
Паттерн двойной вершины M:
Краткое описание паттерна
Также известен как "двойная вершина" (double top). Это паттерн, формирующийся из двух последовательных скругленных вершин.
Такие скругленные вершины часто являются индикатором медвежьего разворота, поскольку нередко возникают после продолжительного бычьего ралли.
Если формируется двойная вершина, второй скругленный максимум обычно располагается немного ниже первого, что указывает на сопротивление и истощение рынка.
Двойные вершины встречаются относительно редко, и их формирование часто свидетельствует о том, что инвесторы стремятся зафиксировать финальную прибыль в рамках бычьего тренда. Подробнее.
Паттерн двойного дна W:
Работает аналогично паттерну двойной вершины M, но в противоположном направлении, подробнее.
Паттерн Stock Line
Мне не удалось найти упоминаний о нем ни в документации, ни в интернете — пока пропустим его.
Паттерны треугольников:

Эти паттерны могут выступать как паттернами продолжения тренда (при подтверждении), так и мощными паттернами разворота (в случае пробоя в противоположную сторону).
Треугольники используют для определения момента сужения торгового диапазона акции или другого финансового инструмента после нисходящего или восходящего тренда. Подробнее.
Получение графических паттернов из MetaTrader 5
Поскольку YOLOv8 работает с изображениями (данными изображений), нам необходимо получить большое количество качественных изображений, которые можно использовать для тестирования и экспериментов с моделью.
К счастью, MetaTrader 5 и язык программирования MQL5 предоставляют функциональность для создания скриншотов любого выбранного графика и торгового символа. Соберем несколько изображений с помощью скрипта.
Файл ChartScreenshots.mq5
#property script_show_inputs input uint BarsToCapture = 1000; //Total Bars input uint BarsShift = 50; //Bars Shift //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- Save current chart position long firstVisibleBar = ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); long chartShift = ChartGetInteger(0, CHART_SHIFT); double priceMax = ChartGetDouble(0, CHART_PRICE_MAX); double priceMin = ChartGetDouble(0, CHART_PRICE_MIN); //--- Set chart properties for clean screenshots ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, true); ChartSetInteger(0, CHART_SHOW_DATE_SCALE, true); ChartSetInteger(0, CHART_SHOW_GRID, false); // Disable grid for cleaner images ChartSetInteger(0, CHART_SHOW_VOLUMES, false); ChartSetInteger(0, CHART_SHOW_TRADE_HISTORY, false); ChartSetInteger(0, CHART_AUTOSCROLL, false); // prevent scrolling int steps = (int)MathCeil((double)BarsToCapture / BarsShift); for(int i = 0; i < steps; i++) { // Shift chart view int shift = i * (int)BarsShift; ChartNavigate(0, CHART_END, -shift); // Wait a moment for the chart to update Sleep(500); // Take screenshot string filename = StringFormat("Screenshots\\%s.%s.%d.png", Symbol(), EnumToString(Period()), i+1); FileDelete(filename); //we delete a previous screenshot with the same name if(!ChartScreenShot(0, filename, 640, 480, ALIGN_CENTER)) { printf("Failed to take screenshot #:%d Error = %d", i+1, GetLastError()); continue; } else { printf("Screenshot saved: %s", filename); } } //--- Restore original chart position ChartNavigate(0, CHART_END, -(int)firstVisibleBar); ChartSetDouble(0, CHART_PRICE_MAX, priceMax); ChartSetDouble(0, CHART_PRICE_MIN, priceMin); ChartSetInteger(0, CHART_SHIFT, chartShift); }
Эта функция делает несколько скриншотов текущего графика на протяжении 1000 баров (по умолчанию), сдвигаясь на 50 баров (по умолчанию) назад относительно предыдущего скриншота.
Перед вызовом функции создания скриншота необходимо убедиться, что график максимально чистый. Даже незначительные элементы шума, такие как линии сетки или тиковые объёмы, могут отвлекать модель от поиска основных паттернов, формирующихся на графике.
ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, true); ChartSetInteger(0, CHART_SHOW_DATE_SCALE, true); // Showing the timescale on a chart ChartSetInteger(0, CHART_SHOW_GRID, false); // Disable grid for cleaner images ChartSetInteger(0, CHART_SHOW_VOLUMES, false); //Prevent displaying the tick volumes ChartSetInteger(0, CHART_SHOW_TRADE_HISTORY, false); //Prevent drawing arrows that displays trading history ChartSetInteger(0, CHART_AUTOSCROLL, false); // prevent scrolling
Все скриншоты будут сохраняться в папке MQL5\Files\Screenshots.
Использование YOLOv8 для поиска паттернов
Ниже приведен минимальный код, необходимый для запуска данной модели и получения предсказанного результата.
Установка
$pip install ultralytics
Начало
from ultralytics import YOLOvv8 model = YOLOvv8.from_pretrained("foduucom/stockmarket-pattern-detection-yolov8") source = 'http://images.cocodataset.org/val2017/000000039769.jpg' model.predict(source=source, save=True)
Однако в вашей среде выполнения этот код вызовет ошибки, поскольку в настоящее время в библиотеке ultralytics отсутствует YOLOvv8 (документация несколько устарела). Ниже приведен корректный способ.
Сначала необходимо импортировать объект YOLO и инициализировать его обученной моделью для данной задачи.
from ultralytics import YOLO import os model = YOLO(os.path.join('Models','model.pt'))
Файл model.pt можно найти здесь. После загрузки сохраните его в подпапке с именем Models в текущем рабочем каталоге.
После этого необходимо вызвать метод predict объекта модели и передать ему имя изображения — и всё, вы получите предсказанный результат :).
model.predict("image_name.png", save=True)
При параметре save=True модель сохраняет итоговое изображение с выделенными на нем обнаруженными паттернами.
Однако это слишком простой и недостаточно гибкий подход. Создадим класс-обертку для данного предиктора, чтобы обеспечить надежный и устойчивый код для анализа и предсказания по нескольким изображениям из папки, в которой хранятся наши скриншоты.
Кроме того, нам необходимо реализовать оптимальный способ обработки предсказаний и визуализации результатов.
Обнаружение паттернов на одном изображении
Конструктор нашего класса принимает на вход объект модели YOLO и папку с изображениями, содержащую все скриншоты, полученные из MetaTrader 5.
class YOLOv8deploy: def __init__(self, model: YOLO, images_folder: str): """A simple class for deploying YOLOv8 model for detecting trading patterns in chart images Args: model (YOLO): YOLO model object images_folder (str): A path where images will be imported from """ self.model = model self.images_folder = images_folder
Нам также потребуется функция внутри класса для получения всех изображений, находящихся в указанной папке.
Эта функция будет полезна при выполнении множественных предсказаний, так как она позволит определить количество доступных изображений в папке, возвращая кортеж, содержащий общее число изображений и их имена в виде списка Python.
def _get_images(self, folder: str, img_extensions: list=['*.png', '*.jpg', '*.jpeg']) -> tuple: """ A function to help us detect the number of images present in a folder Args: folder (str): A path where images are located img_extensions (list, optional): Image filenames extensions. Defaults to ['*.png', '*.jpg', '*.jpeg']. Returns: tuple: Returns the number of images present in a folder and their names """ image_files = [] for ext in img_extensions: image_files.extend(glob.glob(os.path.join(folder, ext))) return (len(image_files), image_files) # Get the number of images and their names
Расширим функцию predict так, чтобы она могла выполнять предсказание для одного изображения. Эта функция также должна предоставлять информацию о найденных паттернах и уровне уверенности (confidence) для каждого из них.
def predict_image(self, img_name: str, hist: bool=True): """This function predicts a single image Args: img_name (str): name of the image hist (bool, optional): When set to false it means the function isn't predicting multiple instances and the outcome will be displayed. Defaults to True. """ if os.path.exists(img_name) == False: # Check if an image exists print(f"Failed to detect patterns, {img_name} not found") return results = self.model.predict(source=img_name, save=True) # Predict an image # Loop through the results for result in results: boxes = result.boxes # Contains bounding boxes and confidence names = result.names # Class index to name mapping if boxes is not None and len(boxes) > 0: for box in boxes: cls_id = int(box.cls[0]) # class id conf = box.conf[0].item() # confidence score label = names[cls_id] print(f"Detected: {label} (confidence: {conf:.2f})") # Open the saved image if this is a single (non-historical) run if not hist: base_name = os.path.splitext(os.path.basename(img_name))[0] + ".jpg" saved_path = os.path.join(result.save_dir, base_name) print("saved path: ",saved_path) if os.path.exists(saved_path): print(f"Opening detected image: {saved_path}") img = cv2.imread(saved_path) cv2.imshow("Detected Patterns", img) cv2.waitKey(0) cv2.destroyAllWindows() else: print("No detections.")
Функция predict от модели YOLOv8 возвращает словарь, содержащий информацию о прямоугольной рамке (bounding box), которая затем отображается на изображении. Эта рамка оборачивает обнаруженный паттерн и добавляет уровень уверенности (confidence) для конкретного распознанного графического паттерна.
После извлечения этой информации мы выводим ее в консоль Python или в командную строку (Command Prompt, CMD).
В конце функции, когда параметр hist установлен в значение False, используется модуль cv2 для отображения предсказанного результата в отдельном диалоговом окне.
Это удобно в случаях, когда необходимо визуализировать итоговое изображение с паттернами, обнаруженными моделью.
Пример.
images_path = r"C:\Users\Omega Joctan\AppData\Roaming\MetaQuotes\Terminal\F4F6C6D7A7155578A6DEA66D12B1D40D\MQL5\Files\Screenshots" # Change this for to the right path on your pc :) symbol = "EURUSD" timeframe = "PERIOD_H1" imgs = 100 pattern_detector = YOLOv8deploy(model=model, images_folder=images_path) pattern_detector.predict_image(img_name=os.path.join(images_path, f"{symbol}.{timeframe}.{11}.png"), hist=False)
У нас есть изображение, полученное с графика EURUSD.PERIOD_H1, с пометкой номера 11 внутри папки Screenshots, которое нужно визуализировать.
Исходное изображение.

Ниже показан результат — изображение, сформированное моделью после вызова функции predict, показанное в отдельном окне.

Обнаружение паттернов на нескольких изображениях
После получения изображений из папки Screenshots мы проходим в цикле по каждому из них и передаем каждое изображение в функцию predict_image, которую мы только что создали.
def predict_images(self): _, image_names = self._get_images(self.images_folder) # Get all images from a folder for image_name in image_names: self.predict_image(img_name=image_name)
Теперь вызовем эту функцию для предсказания по нескольким собранным изображениям. Это похоже на тестирование на истории - мы передаем несколько исторических изображений, чтобы проверить, насколько данная модель является качественной.
pattern_detector.predict_images()Результаты.


Все предсказанные результаты и изображения, созданные моделью, можно найти в текущем рабочем каталоге в папке runs\predict*
Как видите, модель выдала достаточно хорошие предсказания, однако, как и любая когда-либо созданная модель машинного обучения, она имеет свои слабые стороны и ограничения. Ниже приведены некоторые из них.
Предвзятость, риски и ограничения YOLOv8
1. Результативность может зависеть от различий в стилях графиков, разрешении экрана и рыночных условиях.
Крайне важно, чтобы цвета свечей на графике не создавали визуальной путаницы. Фон и свечи должны четко отличаться друг от друга для достижения лучших результатов.
Масштаб графика также имеет значение: слишком крупный масштаб в MetaTrader 5 может привести к отображению неполных паттернов, а слишком мелкий — к появлению шума.
Необходимо найти оптимальный баланс между масштабом графика и размером изображения.
2. Резкие рыночные колебания и шум в торговых данных могут снижать точность.
Флуктуации могут приводить к ложным пробоям и аномальным паттернам. Модель неизбежно будет допускать ошибки на таких графиках и рынках.
3. Модели будет сложно распознавать рыночные паттерны, недостаточно представленные в обучающем наборе данных.
Следует избегать рынков и таймфреймов с неопределенными паттернами. Лучший способ получить от модели максимальную отдачу - это использовать ее на подходящих рынках.
Поиск графических паттернов в MetaTrader 5 с помощью YOLOv8
Как уже отмечалось, модель YOLOv8 работает с изображениями и выдает результат предсказания в формате изображения, что невозможно напрямую прочитать и интерпретировать в MQL5. Однако данный язык поддерживает работу с изображениями в формате bitmap (.BMP), что является хорошей отправной точкой.
Поскольку в MQL5 возможно создать графический объект на основе изображения или встроить изображение в фон графика MetaTrader 5 (что уже неоднократно демонстрировалось), мы откроем изображения, созданные YOLOv8 и содержащие найденные графические паттерны, и отобразим их в MetaTrader 5 на фоне графика, как это было сделано в одной из прошлых статей.
После добавления изображения на фон графика (background) можно скрыть текущие бары, отображаемые на переднем плане, и обновить график как изображение со свечами.
Для этого необходимо внести несколько изменений в наш Python-класс. Начнем с доработки функции predict, чтобы она сохраняла все изображения с прогнозами в определенный (единый) каталог.
Файл: deploy.py
def predict_image(self, img_name: str, save_path: str): """This function predicts a single image Args: img_name (str): name of the image hist (bool, optional): When set to false it means the function isn't predicting multiple instances and the outcome will be displayed. Defaults to True. """ if os.path.exists(img_name) == False: # Check if an image exists print(f"Failed to detect patterns, {img_name} not found") return results = self.model.predict(source=img_name, save=True, project=save_path, name="YOLOv8 Images", exist_ok=True ) # Predict an image # Loop through the results for result in results: boxes = result.boxes # Contains bounding boxes and confidence names = result.names # Class index to name mapping # Convert a jpg image to bmp suitable for MQL5 diplay purposes base_name = os.path.splitext(os.path.basename(img_name))[0] + ".jpg" saved_path = os.path.join(result.save_dir, base_name) convert_jpg_to_bmp(saved_path, os.path.join(result.save_dir, os.path.splitext(os.path.basename(img_name))[0] + '.bmp')) if boxes is not None and len(boxes) > 0: for box in boxes: cls_id = int(box.cls[0]) # class id conf = box.conf[0].item() # confidence score label = names[cls_id] print(f"Detected: {label} (confidence: {conf:.2f})") else: print("No detections.")
С возможностью сохранять изображения в указанную папку с помощью функции predict, мы можем сохранять все файлы в подпапке с именем YOLOv8 Images, созданной в родительском каталоге MQL5\Files.
YOLOv8 создает изображения в формате JPEG или JPG. Чтобы иметь возможность использовать эти изображения в MetaTrader 5, необходимо преобразовать их в формат Bitmap (BMP). Ниже приведена функция для этой задачи.
def convert_jpg_to_bmp(jpg_path, bmp_path): """ Convert a JPG image to 24-bit RGB BMP format Args: jpg_path (str): Path to input JPG file bmp_path (str): Path to save output BMP file """ try: # Open the JPG image with Image.open(jpg_path) as img: # Convert to RGB if not already (handles CMYK, grayscale, etc.) if img.mode != 'RGB': img = img.convert('RGB') # Save as 24-bit BMP img.save(bmp_path, 'BMP') print(f"Successfully converted {jpg_path} to {bmp_path}") return True except Exception as e: print(f"Conversion failed: {str(e)}") return False
Теперь рассмотрим, как можно определять и предсказывать паттерны, присутствующие на одном изображении.
files_path = r"C:\Users\Omega Joctan\AppData\Roaming\MetaQuotes\Terminal\F4F6C6D7A7155578A6DEA66D12B1D40D\MQL5\Files" images_path = os.path.join(files_path, "Screenshots") # Change this for to the right path on your pc :) # .... # .... pattern_detector = YOLOv8deploy(model=model, images_folder=images_path) pattern_detector.predict_image(img_name=image_filename, save_path=files_path)
Этот процесс можно автоматизировать. Через несколько минут после запуска наш скрипт должен считывать изображение из каталога MQL5\Files\Screenshots, выполнять предсказание и сохранять результат в папке MQL5\Files\YOLOv8 Images. Теперь подготовим корректную среду для развёртывания полученного изображения в формате Bitmap (.BMP) на графике MetaTrader 5.
files_path = r"C:\Users\Omega Joctan\AppData\Roaming\MetaQuotes\Terminal\F4F6C6D7A7155578A6DEA66D12B1D40D\MQL5\Files" images_path = os.path.join(files_path, "Screenshots") # Change this for to the right path on your pc :) symbol = "EURUSD" timeframe = "PERIOD_H1" def scheduledYOLOv8Run(): now = datetime.now() # Get the current local date and time # Extract current day and hour date = now.day current_day = now.weekday() # e.g., 'Wednesday' current_hour = now.strftime("%H") # e.g., '14' for 2 PM in 24-hour format image_filename = os.path.join(images_path, f"{symbol}.{timeframe}.{date}.{current_day+1}.{current_hour}.png") pattern_detector = YOLOv8deploy(model=model, images_folder=images_path) pattern_detector.predict_image(img_name=image_filename, save_path=files_path) print(f"Processed image at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") # Schedule the pattern detection after every minute(s) schedule.every(1).minutes.do(scheduledYOLOv8Run) print("Scheduler started. Press Ctrl+C to stop.") # Run forever while True: schedule.run_pending() time.sleep(1)
Теперь подготовим среду для развертывания полученного изображения в формате Bitmap (.BMP) на графике MetaTrader 5.
Начнем с инициализации функции обработки таймера, которая позволит автоматизировать процесс создания скриншота и обновления графика изображением с предсказанными (обнаруженными) паттернами.
Файл: YOLOv8 EA.mq5
input uint chart_scale = 3; input uint timer_seconds = 60; int chart_width, chart_height; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- if (!EventSetTimer(timer_seconds)) { printf("%s failed to set the timer, Error = %d",__FUNCTION__,GetLastError()); return INIT_FAILED; } showBars(true); //--- return(INIT_SUCCEEDED); }
Функция showBars отвечает за очищение и подготовку подходящего места на графике для создания скриншота.
void showBars(bool show=true) { //--- Cleaning the chart ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, true); ChartSetInteger(0, CHART_SHOW_DATE_SCALE, true); ChartSetInteger(0, CHART_SHOW_GRID, false); // Disable grid for cleaner images ChartSetInteger(0, CHART_SHOW_VOLUMES, false); ChartSetInteger(0, CHART_SHOW_TRADE_HISTORY, false); ChartSetInteger(0, CHART_AUTOSCROLL, true); // prevent scrolling ChartSetInteger(0, CHART_SHIFT, true); if (ChartGetInteger(0, CHART_SCALE) != chart_scale) ChartSetInteger(0, CHART_SCALE, chart_scale); if (show) { ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrWhite); ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrBlack); ChartSetInteger(0, CHART_COLOR_CHART_UP, clrTomato); ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrTomato); ChartSetInteger(0, CHART_COLOR_CHART_DOWN, clrLightSeaGreen); ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrLightSeaGreen); ChartSetInteger(0, CHART_SHOW_ASK_LINE, true); ChartSetInteger(0, CHART_SHOW_BID_LINE, true); ChartSetInteger(0, CHART_COLOR_ASK, clrTurquoise); } else { ChartSetInteger(0, CHART_COLOR_BACKGROUND, clrWhite); ChartSetInteger(0, CHART_COLOR_FOREGROUND, clrBlack); ChartSetInteger(0, CHART_COLOR_CHART_UP, clrWhite); ChartSetInteger(0, CHART_COLOR_CANDLE_BULL, clrWhite); ChartSetInteger(0, CHART_COLOR_CHART_DOWN, clrWhite); ChartSetInteger(0, CHART_COLOR_CANDLE_BEAR, clrWhite); ChartSetInteger(0, CHART_SHOW_ASK_LINE, true); ChartSetInteger(0, CHART_SHOW_BID_LINE, true); ChartSetInteger(0, CHART_COLOR_ASK, clrTurquoise); } ChartRedraw(); }
Когда эта функция вызывается со значением false, все свойства графика (включая цвета японских свечей) устанавливаются равными цвету фона графика — таким образом все становится невидимым.
Это необходимо, поскольку мы будем размещать изображение на фоне текущего графика, и бары на переднем плане не должны отображаться поверх изображения и создавать визуальный беспорядок.
Ниже приведена функция, которая преобразует изображение Bitmap (.BMP) в объект, а затем назначает его фоном текущего графика.
//+------------------------------------------------------------------+ //| Function to set a BMP image as chart background | //+------------------------------------------------------------------+ bool chartBackGroundSet(string filename, int width, int height) { string obj_name = "background-img"; if(!ObjectCreate(0,obj_name,OBJ_BITMAP_LABEL,0,0,0)) { printf("%s failed to create a bitmap in the chart window! Error = %s",__FUNCTION__,ErrorDescription(GetLastError())); return(false); } //--- set the path to the image file if(!ObjectSetString(0,obj_name,OBJPROP_BMPFILE, filename)) { printf("%s failed to load the image! Error = %s",__FUNCTION__,ErrorDescription(GetLastError())); return(false); } //--- Position the image to cover the entire chart ObjectSetInteger(0, obj_name, OBJPROP_XDISTANCE, 0); ObjectSetInteger(0, obj_name, OBJPROP_YDISTANCE, 0); ObjectSetInteger(0, obj_name, OBJPROP_XSIZE, width); ObjectSetInteger(0, obj_name, OBJPROP_YSIZE, height); //--- Send the image to the background ObjectSetInteger(0, obj_name, OBJPROP_BACK, true); ObjectSetInteger(0, obj_name, OBJPROP_ZORDER, -1); //--- Make sure the object is visible ObjectSetInteger(0, obj_name, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, obj_name, OBJPROP_HIDDEN, true); //--- Redraw the chart to see changes ChartRedraw(0); //--- return true; }
Наконец, автоматизируем процесс создания скриншотов и их отправки в каталог Screenshots для последующего чтения нашим Python-скриптом. Также автоматизируем процесс чтения предсказанных изображений из папки YOLOv8 Images и процесс отрисовки изображения на графике MetaTrader 5.
void OnTimer(void) { //--- showBars(true); //explicitly show the bars // Clear the objects before taking a screenshot ObjectsDeleteAll(0); ObjectsDeleteAll(0,0); if (takeScreenShot()) { Print("Screen shot taken: ",TimeCurrent()); Sleep(100); } chart_width = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS); chart_height = (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS); //--- Take screenshot MqlDateTime time_struct; TimeToStruct(TimeLocal(), time_struct); string filename = StringFormat("\\Files\\YOLOv8 Images\\%s.%s.%d.%d.%d.bmp",Symbol(),EnumToString(Period()),time_struct.day, time_struct.day_of_week, time_struct.hour); string fileshort_name = filename; bool checkfile = false; if (StringReplace(fileshort_name, "\\Files\\","")>0) checkfile = true; //If the parent folder was removed we can proceed to check if a file exists before drawing an object if (checkfile) while (!FileIsExist(fileshort_name)) { printf("%s not found",fileshort_name); return; } //--- Set the image with patterns detected to a chart if (!chartBackGroundSet(filename, chart_width, chart_height)) return; showBars(false); }
В завершение на графике EURUSD, PERIOD_H1 (тот же таймфрейм, что и в Python-скрипте) мы запустили советника. Python-скрипт был запущен, а таймер установлен на 60 секунд.
После 60 секунд на графике EURUSD платформа MetaTrader 5 получила изображение от модели.

Работает!
Метод использования изображения в качестве фона графика является довольно примитивным и предполагает, что размер графика остается постоянным или, по крайней мере, не меняется в течение времени, заданного в функции таймера.
Таким образом, изменение размера графика может на некоторое время нарушить процесс отрисовки изображения. Я рекомендую использовать метод, рассмотренный здесь, чтобы реализовать более устойчивый способ визуализации изображения в качестве фона графика.
Заключительные мысли
На мой взгляд, YOLOv8 — впечатляющая модель. Как и любая другая модель машинного обучения, она имеет свои ограничения и недостатки, однако для задач поиска графических паттернов она действительно корректно работает. Поэтому стоит отдать должное ее разработчикам, поскольку в прошлом я как-то пытался создать аналогичную модель для этой задачи, но ничего достойного у меня не получилось.
Хотя мы часто используем модели ИИ для автоматизации торговых стратегий, данная модель пока не является практичной для алгоритмической торговли, поскольку она генерирует изображения, которые на данный момент может интерпретировать только человек. Скорее, это интересный инструмент для поиска паттернов в ручной торговле. Чтобы использовать ее в алгоритмических стратегиях, можно реализовать соединение между Python и MetaTrader 5 для передачи сырых данных в текстовом или JSON-формате о состоянии модели и предсказаниях, возвращаемых методом predict.
Всем удачи!
Оставайтесь с нами и вносите свой вклад в разработку алгоритмов машинного обучения для языка MQL5 в этом GitHub-репозитории.
Таблица вложений
Имя файла и путь | Описание и назначение |
|---|---|
| Experts\YOLOv8 EA.mq5 | Советник для сбора скриншотов с графика и добавления прогнозного изображения от YOLOv8 к текущему графику. |
| Include\errordescription.mqh | Библиотека для преобразования кодов ошибок, генерируемых в MetaTrader 5 и MQL5, из integer в удобочитаемые строки. |
| Scripts\ChartScreenshots.mq5 | Скрипт для создания исторических скриншотов с указанного графика в MetaTrader 5. |
| YOLOv8 Proj\test.py | Скрипт на Python для тестирования модели YOLOv8 на нескольких изображениях. |
| YOLOv8 Proj\deploy.py | Скрипт на Python для развертывания и непрерывного запуска модели YOLOv8. |
| YOLOv8 Proj\requirements.txt | Содержит все зависимости Python, используемые в проекте, и номера их версий. |
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/18143
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Торговые инструменты на языке MQL5 (Часть 6): Динамическая голографическая панель с импульсной анимацией и элементами управления
Нейросети в трейдинге: Адаптивная факторная токенизация (Окончание)
Создание самооптимизирующихся советников на MQL5 (Часть 7): Одновременная торговля на нескольких периодах
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования



