
Разработка инструментария для анализа движения цен (Часть 9): Внешние библиотеки
Введение
Финансовые рынки могут быть сложными, что часто создает трудности для трейдеров и аналитиков в плане точной обработки и интерпретации данных. Чтобы преодолеть эти проблемы, были разработаны различные библиотеки, упрощающие анализ рынка, каждая из которых предназначена для обработки данных способами, соответствующими определенным целям. Хотя библиотеки MQL5 обычно используются для создания торговых стратегий и индикаторов, внешние библиотеки, такие как инструменты анализа данных Python, предоставляют дополнительные ресурсы для более расширенного и глубокого анализа.
В предыдущих статьях я сосредоточился на ценовом действии и анализе данных, в первую очередь изучая генерацию сигналов посредством вычислений и показателей, обрабатываемых советниками на языке MQL5. Однако эти статьи были ограничены анализом на основе MQL5. В этой статье описывается изменение, заключающееся в интеграции внешних библиотек, специально разработанных для расширенного анализа данных. Используя библиотеку Python Pandas, мы можем открыть новые возможности для трейдеров, предоставляя более широкий спектр аналитических возможностей для удовлетворения различных потребностей.
Данный метод не заменяет MQL5, а позиционирует его как ядро данной системы. MQL5-советник выступает в роли моста, обеспечивая взаимодействие с внешними библиотеками и серверами для создания более надежной и гибкой аналитической структуры. Я хотел бы подчеркнуть, что эта статья — только начало изучения углубленной аналитики, и я с нетерпением ожидаю возможности представить более всесторонние идеи и методы в будущих обсуждениях.
Давайте посмотрим, как мы подойдем к решению этой задачи:
Обзор стратегии
Основная цель этой системы — генерация торгового сигнала с использованием библиотеки Python Pandas, используя ее возможности интерпретации данных. В этом разделе мы более подробно рассмотрим, как основная логика выполняется системой. Общий обмен данными происходит между MQL5-советником и Python, при этом между ними происходят различные процессы, прежде чем сигнал в конечном итоге отобразится на графике. Давайте выполним шаги, описанные ниже, чтобы понять, как работает система.
1. Советник > Python:
- Советник собирает максимумы, минимумы, открытия, закрытия и объемы предыдущего дня за 10 дней.
- Отправляет данные на сервер Python.
- Форматирует данные в строку CSV и отправьте ее с помощью HTTP-запроса POST на сервер Python.
2. Python:
- Python получает данные и обрабатывает полученные данные с помощью библиотек, таких как Pandas.
- Анализирует данные, чтобы сгенерировать торговый сигнал, среднюю цену и объем, а затем создает объяснение.
3. Python > советник:
- Python отправляет сгенерированный сигнал, среднюю цену, объем и объяснение обратно в советник через HTTP-ответ.
4. Советник:
- Советник получает и анализирует ответ, извлекает сигнал, среднюю цену, средний объем и объяснение из ответа.
- Если сигнал отличается, обновляет график с учетом нового сигнала и отображает его.
Для более подробного понимания обратимся к следующей диаграмме.
Рис 1. Логическая схема
Python
Python — универсальный язык программирования, известный своей простотой и широким спектром применения. Его обычно используют для анализа данных, машинного обучения, веб-разработки и автоматизации, а также для других задач. Python играет решающую роль в выполнении расширенного анализа данных, особенно с помощью таких библиотек, как Pandas, которые предоставляют эффективные инструменты для обработки и анализа данных. Python также создает сервер для взаимодействия MQL5 и его библиотеками. Используя Python для обработки сложных наборов данных, система генерирует торговые сигналы на основе исторических рыночных данных, которые затем передаются в MQL5-советник для помощи в принятии торговых решений в реальном времени.
Рассмотрим установку Python, создание скрипта и его запуск шаг за шагом.
- Загрузите установщик Python на официальном сайте Python
- Запустите установщик
Важно: обязательно установите флажок Add Python to PATH (добавить Python в PATH), прежде чем кликнуть Install Now (установить сейчас). Это упрощает запуск Python из командной строки.
- Завершите установку
Установщик начнет процесс установки. Дождитесь окончания. После завершения установки нажмите Close (закрыть).
- Проверьте установку
Откройте командную строку (нажмите Windows + R, введите cmd и нажмите Enter). Введите python --version и нажмите Enter. Если Python установлен правильно, вы должны увидеть версию Python (например, Python 3.x.x).
После успешной установки Python, теперь стоит рассмотреть возможность установки Flask и Pandas. Flask — это легкий веб-фреймворк для Python, используемый для разработки веб-приложений. Он разработан с упором на простоту, гибкость и удобство использования. Flask используется для настройки простого веб-сервера, обеспечивающего взаимодействие между MQL5-советником и инструментами анализа данных Python. Советник отправляет данные во Flask (через HTTP-запросы), который обрабатывает данные с помощью библиотек Python, в данном случае Pandas, и возвращает торговый сигнал советнику.
Чтобы установить Flask и Pandas с помощью командной строки, выполните следующие действия:
Откройте командную строку
- Нажмите Windows + R, введите cmd и нажмите Enter.
Убедитесь, что установлен pip (установщик пакетов Python)
- Сначала проверьте, установлен ли pip, выполнив:
pip --version
- Если pip установлен, вы увидите номер версии. Если не установлен, выполните следующие шаги для установки. PIP (Python Package Installer) обычно устанавливается автоматически вместе с Python. Если его нет, загрузите get-pip.py и запустите его с помощью команды get-pip.py.
Установите Flask
- Чтобы установить Flask, выполните следующую команду в командной строке:
pip install Flask
- Дождитесь окончания установки. Flask будет установлен и готов к использованию.
Установите Pandas
- Чтобы установить Pandas, выполните эту команду:
pip install pandas
- Аналогично дождитесь завершения установки.
Проверьте установку
- После установки обоих пакетов вы можете проверить установку, выполнив следующие команды:
python -c "import flask; print(flask.__version__)" python -c "import pandas; print(pandas.__version__)"
- Это должно вывести на экран установленные версии Flask и Pandas.
Теперь вы можете приступить к созданию скрипта Python. Лично я предпочитаю использовать для этой задачи Notepad++. Чтобы создать скрипт, откройте Notepad++, создайте новый файл и установите язык Python, выбрав его в меню Language (язык). Готовый скрипт сохраните в каталоге, который легко найти. Обязательно сохраните файл с расширением .py, которое идентифицирует его как скрипт Python.
Скрипт Python
import pandas as pd import flask from flask import request, jsonify app = flask.Flask(__name__) app.config["DEBUG"] = True @app.route('/analyze', methods=['POST']) def analyze_csv(): try: # Read CSV data from the POST request csv_data = request.data.decode('utf-8') # Write the CSV data to a file (optional, for debugging) with open('received_data.csv', 'w') as file: file.write(csv_data) # Load the CSV data into a DataFrame from io import StringIO data = StringIO(csv_data) df = pd.read_csv(data) # Ensure the CSV has the correct columns required_columns = ['date', 'prev_high', 'prev_low', 'prev_open', 'prev_close', 'prev_volume'] for column in required_columns: if column not in df.columns: return jsonify({"error": f"Missing column: {column}"}), 400 # Print the received metrics for debugging print("Received metrics:") print(df) # Perform analysis (Example: Calculate average price and volume) df['average_price'] = (df['prev_high'] + df['prev_low'] + df['prev_open'] + df['prev_close']) / 4 average_price = df['average_price'].mean() # Average of all the average prices average_volume = df['prev_volume'].mean() # Average volume # Print the computed averages print(f"Average Price: {average_price}") print(f"Average Volume: {average_volume}") # Create a trading signal based on a simple rule last_close = df['prev_close'].iloc[-1] if last_close > average_price: signal = "BUY" signal_explanation = f"The last close price ({last_close}) is higher than the average price ({average_price})." else: signal = "SELL" signal_explanation = f"The last close price ({last_close}) is lower than the average price ({average_price})." # Print the signal and explanation print(f"Generated Signal: {signal}") print(f"Signal Explanation: {signal_explanation}") # Return the signal as JSON return jsonify({ "signal": signal, "average_price": average_price, "average_volume": average_volume, "signal_explanation": signal_explanation }) except Exception as e: return jsonify({"error": str(e)}), 500 if __name__ == '__main__': app.run(host='189.7.6.8', port=5877)
Чтобы запустить скрипт, откройте командную строку на вашем компьютере.
Выполните команду:
cd C:\Users\pathway to your python script folder
А затем - команду:
python filename.py
Используйте точно то имя, которое вы присвоили своему скрипту при его выполнении. После запуска скрипта будет указано, что порт активно прослушивается.
Running on http://189.7.6.8:5877
Основные функции
Initialization (OnInit)
Эта функция запускается при первой инициализации советника в MetaTrader. Она используется для настройки любых ресурсов или конфигураций, необходимых советнику. В этом случае она просто выводит сообщение в журнал, указывающее, что советник готов начать взаимодействие с сервером Python.
int OnInit() { Print("Expert initialized. Ready to send data to Python."); return(INIT_SUCCEEDED); }
Возвращаемое значение INIT_SUCCEEDED означает, что инициализация прошла успешно.
Deinitialization (OnDeinit)
Эта функция срабатывает при удалении советника или закрытии платформы MetaTrader. Обычно она используется для операций очистки, таких как освобождение ресурсов или закрытие открытых файлов. Здесь она просто выводит сообщение о том, что советник был деинициализирован и больше не действует.
void OnDeinit(const int reason) { Print("Expert deinitialized."); }
OnTick (Core Functionality)
Это основная функция советника, которая выполняется каждый раз, когда меняются рыночные условия (на каждом новом тике).
void OnTick() { // Check if enough time has passed since the last signal update if(TimeCurrent() - lastSignalTime < signalInterval) { return; // Skip if it's too soon to update } // Collect data and prepare CSV for Python string csvData = "date,prev_high,prev_low,prev_open,prev_close,prev_volume\n"; // Get the previous trend data for the last `trendDays` for(int i = 1; i <= 10; i++) // You can adjust the trendDays here { datetime prevDate = iTime(Symbol(), PERIOD_D1, i); double prevHigh = iHigh(Symbol(), PERIOD_D1, i); double prevLow = iLow(Symbol(), PERIOD_D1, i); double prevOpen = iOpen(Symbol(), PERIOD_D1, i); double prevClose = iClose(Symbol(), PERIOD_D1, i); long prevVolume = iVolume(Symbol(), PERIOD_D1, i); csvData += StringFormat("%s,%.5f,%.5f,%.5f,%.5f,%ld\n", TimeToString(prevDate, TIME_DATE | TIME_MINUTES), prevHigh, prevLow, prevOpen, prevClose, prevVolume); } // Save data to CSV file string fileName = StringFormat("%s_analytics.csv", Symbol()); int fileHandle = FileOpen(fileName, FILE_WRITE | FILE_CSV | FILE_ANSI); if(fileHandle != INVALID_HANDLE) { FileWriteString(fileHandle, csvData); FileClose(fileHandle); Print("CSV file created: ", fileName); } }
Она также выполняет следующие операции:
- Проверка интервала сигнала: : Советник сначала проверяет, прошло ли достаточно времени с момента последнего обновления сигнала, используя TimeCurrent(). В противном случае обработка будет пропущена.
- Сбор данных: Советник собирает рыночные данные за последние 10 дней (или больше, если вы измените значение в цикле), включая: максимум, минимум, открытие, закрытие и объем предыдущего дня.
- Форматирование данных: Затем он форматирует эти данные в CSV для легкой передачи на сервер Python.
- Сохранение CSV-файла: Данные сохраняются в виде CSV-файла с именем <symbol>_analytics.csv. Если создание и запись файла прошли успешно, выводится сообщение об успешном завершении.
HTTP-запрос к серверу Python (WebRequest)
string headers = "Content-Type: application/json\r\n"; char result[]; string resultHeaders; int responseCode = WebRequest( "POST", // HTTP method pythonUrl, // URL headers, // Custom headers timeout, // Timeout in milliseconds data, // Data to send result, // Response content resultHeaders // Response headers ); if(responseCode == 200) { string response = CharArrayToString(result); Print("Received response: ", response); } else { Print("Error: HTTP request failed with code ", responseCode); }
После подготовки данных в формате CSV советник отправляет эти данные на сервер Python через HTTP POST.
- Headers: Заголовок Content-Type установлен на application/json, который сообщает серверу, что отправляемые данные имеют формат JSON.
- WebRequest: Функция WebRequest используется для отправки HTTP-запроса POST на сервер Python. Функция возвращает:
1) responseCode: Код ответа HTTP (например, 200 при успешном завершении).
2) result: Содержимое ответа сервера (обычно результаты анализа).
Рис 2. Схема WebRequest
- Если запрос успешен (responseCode == 200), содержимое ответа преобразуется из массива символов в строку, и выводится сообщение об успешном выполнении. При неудачном запросе отображается сообщение об ошибке.
Анализ и отображение ответа
if(responseCode == 200) { string signal = ""; string avgPrice = ""; string avgVolume = ""; string explanation = ""; // Extract signal, avgPrice, avgVolume, and explanation from the response int signalStart = StringFind(response, "\"signal\":"); int signalEnd = StringFind(response, "\"average_price\":"); int explanationStart = StringFind(response, "\"signal_explanation\":"); int avgPriceStart = StringFind(response, "\"average_price\":"); int avgVolumeStart = StringFind(response, "\"average_volume\":"); if(signalStart != -1 && signalEnd != -1) { signal = StringSubstr(response, signalStart + 10, signalEnd - signalStart - 12); } if(explanationStart != -1) { explanation = StringSubstr(response, explanationStart + 23, StringFind(response, "\"", explanationStart + 23) - (explanationStart + 23)); } if(avgPriceStart != -1) { avgPrice = StringSubstr(response, avgPriceStart + 16, StringFind(response, "\"", avgPriceStart + 16) - (avgPriceStart + 16)); } if(avgVolumeStart != -1) { avgVolume = StringSubstr(response, avgVolumeStart + 18, StringFind(response, "\"", avgVolumeStart + 18) - (avgVolumeStart + 18)); } // Update the chart if the signal has changed if(signal != lastSignal) { lastSignal = signal; lastSignalTime = TimeCurrent(); // Update last signal time string receivedSummary = "Signal: " + signal + "\n" + "Avg Price: " + avgPrice + "\n" + "Avg Volume: " + avgVolume + "\n" + "Explanation: " + explanation; Print("Received metrics and signal: ", receivedSummary); Comment(receivedSummary); // Display it on the chart } }
Получив ответ от сервера Python, советник анализирует ответ для извлечения ключевых данных, таких как:
- Signal - торговый сигнал (например, buy или sell).
- Avg Price - средняя цена, полученная в результате анализа.
- Avg Volume - средний объем сделок.
- Explanation - объяснение причины возникновения сигнала.
Функция использует StringFind и StringSubstr для извлечения этих значений из строки ответа.
Если сигнал изменился с момента последнего обновления (signal != lastSignal):
1) Обновляются переменные lastSignal и lastSignalTime.
2) Отображается новый сигнал, средняя цена, объем и объяснение в виде комментария на графике с помощью функции Comment().
Обновление и отображение сигнала
Эта часть интегрирована в предыдущий шаг, где сигнал обновляется и отображается на графике.
if(signal != lastSignal) { lastSignal = signal; lastSignalTime = TimeCurrent(); // Update last signal time string receivedSummary = "Signal: " + signal + "\n" + "Avg Price: " + avgPrice + "\n" + "Avg Volume: " + avgVolume + "\n" + "Explanation: " + explanation; Print("Received metrics and signal: ", receivedSummary); Comment(receivedSummary); // Display it on the chart }
Если сигнал изменился (т.е. отличается от предыдущего), советник:
- Обновляет переменные lastSignal и lastSignalTime.
- Создает строковую сводку, содержащую сигнал, среднюю цену, средний объем и пояснение.
- Отображает сводку на графике в виде комментария и выводит ее в журнал.
CharArrayToString (Utility Function)
string CharArrayToString(char &arr[]) { string result = ""; for(int i = 0; i < ArraySize(arr); i++) { result += StringFormat("%c", arr[i]); } return(result); }
Эта служебная функция используется для преобразования массива символов (полученного из HTTP-ответа) в строку. Она просматривает каждый элемент массива символов и добавляет соответствующий символ к результирующей строке.
Каждый из этих шагов предназначен для обработки определенной части процесса: сбора данных, отправки их на сервер Python, получения анализа и обновления графика с торговым сигналом. Такой подход гарантирует, что советник сможет работать автономно, собирать соответствующие рыночные данные и принимать решения на основе аналитики, реализованной на языке Python.
Результаты
Первый шаг — убедиться, что ваш скрипт Python запущен и активно прослушивает требуемый сервер. Подробные инструкции по настройке и запуску скрипта сморите в разделе Python выше. При активном прослушивании мы должны увидеть:Running on http://189.7.6.8:5877
Обратите внимание, что API и хост, упомянутые выше, не являются фактически используемыми, а были созданы в образовательных целях. Далее приступаем к запуску советника MQL5. Если соединение между MQL5 и сервером Python успешно установлено, вы увидите сообщения журнала на вкладке "Эксперты" графика. Кроме того, скрипт Python, запущенный в командной строке, отобразит полученные метрики.
В командной строке отобразится следующее:
189.7.6.8 - - [21/Jan/2025 10:53:44] "POST /analyze HTTP/1.1" 200 - Received metrics: date prev_high prev_low prev_open prev_close prev_volume 0 2025.01.20 00:00 868.761 811.734 826.389 863.078 83086.0 1 2025.01.19 00:00 856.104 763.531 785.527 826.394 82805.0 2 2025.01.18 00:00 807.400 752.820 795.523 785.531 82942.0 3 2025.01.17 00:00 886.055 790.732 868.390 795.546 83004.0 4 2025.01.16 00:00 941.334 864.202 932.870 868.393 83326.0 5 2025.01.15 00:00 943.354 870.546 890.620 932.876 83447.0 6 2025.01.14 00:00 902.248 848.496 875.473 890.622 83164.0 7 2025.01.13 00:00 941.634 838.520 932.868 875.473 82516.0 8 2025.01.12 00:00 951.350 868.223 896.455 932.883 83377.0 9 2025.01.11 00:00 920.043 857.814 879.103 896.466 83287.0 10 NaN NaN NaN NaN NaN NaN
Приведенная выше информация будет использоваться pandas для анализа и генерации сигналов. Данные за десятый день показывают NaN, поскольку день еще не закрылся, а это значит, что анализ в первую очередь опирается на значения, полученные за предыдущие дни. Однако он также включает в себя текущие уровни цен десятого дня, которые являются неполными. Ниже вы можете ознакомиться с результатами регистрации и анализа, отображаемыми pandas в командной строке (CMD).
Average Price: 865.884525 Average Volume: 83095.4 Generated Signal: SELL Signal Explanation: The last close price (nan) is lower than the average price (865.884525).
MetaTrader 5 отобразит следующее:
Начнем с проверки регистрации на вкладке "Эксперты". Ниже представлены результаты.
2025.01.21 10:50:28.106 External Flow (Boom 300 Index,D1) CSV file created: Boom 300 Index_analytics.csv 2025.01.21 10:50:28.161 External Flow (Boom 300 Index,D1) Received response: { 2025.01.21 10:50:28.161 External Flow (Boom 300 Index,D1) "average_price": 865.884525, 2025.01.21 10:50:28.161 External Flow (Boom 300 Index,D1) "average_volume": 83095.4, 2025.01.21 10:50:28.161 External Flow (Boom 300 Index,D1) "signal": "SELL", 2025.01.21 10:50:28.161 External Flow (Boom 300 Index,D1) "signal_explanation": "The last close price (nan) is lower than the average price (865.884525)."
Результат также отобразится на графике, и процесс будет повторяться в зависимости от настроек времени ожидания, указанных во входных параметрах.
Рис. 3. Отображаемый результат
Ниже представлен график прибыльной сделки, которую я разместил на основе сгенерированного сигнала и дополнительного анализа. Для большей наглядности торговля отображается на M1 (1 минута).
Рис 4. Размещенная сделка
Заключение
Описав шаги по внедрению расширенного анализа с использованием внешних библиотек, таких как pandas, для этого проекта, мы заложили прочную основу для разработки более продвинутых инструментов для анализа ценовых действий и рынка. Я призываю каждого трейдера рассматривать это как общее руководство для понимания ожидаемых движений рынка. Однако для оптимального исполнения сделок используйте другие знакомые вам стратегии. Я буду рад вашим отзывам и комментариям.
Дата | Название инструмента | Описание | Версия | Обновления | Примечания |
---|---|---|---|---|---|
01/10/24 | Chart Projector | Скрипт для наложения эффекта призрака на движение цены за предыдущий день. | 1.0 | Первоначальная версия | Первый инструмент в Lynnchris Tools Chest |
18/11/24 | Analytical Comment | Предоставляет информацию за предыдущий день в табличном формате, а также прогнозирует будущее направление рынка. | 1.0 | Первоначальная версия | Второй инструмент в Lynnchris Tools Chest |
27/11/24 | Analytics Master | Регулярное обновление рыночных показателей каждые два часа | 1.01 | Вторая версия | Третий инструмент в Lynnchris Tools Chest |
02/12/24 | Analytics Forecaster | Регулярное обновление рыночных показателей каждые два часа с интеграцией с Telegram | 1.1 | Третья версия | Инструмент номер 4 |
09/12/24 | Volatility Navigator | Советник анализирует рыночные условия с помощью полос Боллинджера, RSI и ATR. | 1.0 | Первоначальная версия | Инструмент номер 5 |
19/12/24 | Mean Reversion Signal Reaper | Анализирует рынок и генерирует сигналы, используя стратегию возврата к среднему | 1.0 | Первоначальная версия | Инструмент номер 6 |
9/01/2025 | Signal Pulse | Анализирует несколько таймфреймов | 1.0 | Первоначальная версия | Инструмент номер 7 |
17/01/2025 | Metrics Board | Панель с кнопкfvb для анализа | 1.0 | Первоначальная версия | Инструмент номер 8 |
21/01/2025 | External Flow | Аналитика с помощью внешних библиотек | 1.0 | Первоначальная версия | Инструмент номер 9 |
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/16967
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.




- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования