English 中文 Español Deutsch 日本語 Português
preview
Использование JSON Data API в MQL-проектах

Использование JSON Data API в MQL-проектах

MetaTrader 5Торговые системы | 16 января 2025, 08:08
709 21
Sara Sabaghi
Sara Sabaghi

Введение и предыстория

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

Использование данных API в советниках (EA) может дать новое и более глубокое понимание рынка трейдинга, которое будет способствовать принятию обоснованных решений, созданию более динамичных торговых стратегий и более эффективному управлению рисками. С помощью данных API трейдеры могут повысить точность торговых сигналов, применяя передовые технические индикаторы и сложные графические инструменты. Подобная интеграция расширяет возможности таких платформ, как MetaTrader, и обеспечивает доступ к таким ценным средствам рыночной аналитики, как обработка текстов на естественном языке (NLP) для анализа рыночных настроений, и к фундаментальным данным и новостям.


Знакомство с Ziwox API

Ziwox — система анализа данных на рынке Форекс, содержащая бесплатные API-сервисы. API обеспечивает трейдеров подробной информацией о рынке, включая цены, технические индикаторы, анализ настроений и фундаментальные данные. Он поддерживает основные и второстепенные валютные пары и обеспечивает важные показатели, такие как фундаментальный уклон, прогнозы на базе ИИ, статистика розничных трейдеров, отчеты COT, технические поддержка и сопротивление, рыночные настроение ("склонность к риску", "неприятие риска"), доходность облигаций и индекс VIX. Этот содержательный набор данных позволяет проводить многосторонний анализ рынка, сочетая технические, фундаментальные и аналитические данные для создания революционных инструментов.

Здесь интересно, что наряду с ценовыми и техническими данными мы получим доступ к данным, сгенерированным искусственным интеллектом или реальными аналитиками. Некоторые из них включали в себя: фундаментальный анализ валютных пар, проводимый группой аналитиков, результаты работы системы обработки естественного языка (NLP) как настроения на рынке новостей Форекс и прогноз цен, сделанный ИИ.

API прост в применении: для генерации его ключа и доступа к данным в текстовом или JSON-формате достаточно просто зарегистрироваться. Такая доступность наряду с большим охватом данных делает его неоценимым инструментом повышения качества торговых стратегий и разработки пользовательских индикаторов или автоматизированных торговых систем.

Что такое API?


Узнаем немного больше о том, что такое API.

API — механизмы, позволяющие двум программным компонентам взаимодействовать с помощью набора определений и протоколов. Например, программный комплекс метеослужбы содержит ежедневные данные о погоде. Приложение "Погода" на телефоне "общается" с этой системой через API и показывает на экране ежедневные новости о погоде.

API — аббревиатура от Application Programming Interface (интерфейс прикладного программирования). Интерфейс можно рассматривать как договор обслуживания между двумя приложениями. Этот договор определяет способы их взаимодействия с помощью запросов и ответов. В их API-документации есть информация о том, как разработчики структурируют эти запросы и ответы.

Архитектуру API обычно описывают с позиций "клиент — сервер". Программу, отправляющую запрос, называют клиентом, а отправляющую ответ — сервером. Так, в примере с погодой база данных — это сервер, а мобильное приложение — клиент.


Форматы ответов API:

Есть разные форматы ответов или обмена данными API. Формат может меняться в зависимости от цели создания API и того, с какими еще Приложениями он связан.

Эти ответы могут быть в формате стандартов JSON, HTML, TEXT, XML или CSV.

Краткое знакомство с этой стандартной моделью:

1. JSON: JSON  — легкий, понятный человеку формат обмена данных, благодаря простоте и гибкости используемый в ответах API. Он представляет данные в виде пар "ключ-значение", что облегчает их анализ и обработку на разных языках программирования.

Пример ответа в формате JSON:

{
  "id": 5687,
  "source": "oanda",
  "symbol": "EURUSD",
  "price": "1.08562",
  "high": "1.09211",
  "low": "1.08154"
}


2. XML: XML  (eXtensible Markup Language, расширяемый язык разметки) — еще один широко распространенный формат представления структурированных данных в ответах API. В отличие от JSON, XML для определения иерархических структур данных использует теги, обеспечивая более точное, но структурированное представление. Это похоже на теги HTML в веб-дизайне и веб-структурах. Хотя формат JSON предпочтительнее из-за его простоты и удобочитаемости, XML сохраняет актуальность в некоторых областях, например в корпоративных системах и при традиционных интеграциях.

Пример XML в API новостей Forex Factory:

<event>
<title>German Trade Balance</title>
<country>EUR</country>
<date>
<![CDATA[ 07-07-2024 ]]>     </date>
<time>
<![CDATA[ 8:30am ]]>
</time>
<impact><![CDATA[ Low ]]></impact>

<forecast><![CDATA[ 19.9B ]]></forecast>
<previous><![CDATA[ 22.1B ]]></previous>
<url>
<![CDATA[ https://www.forexfactory.com/calendar/125-eur-german-trade-balance ]]>
</url>

</event>


3. Другие форматы: Наряду с JSON и XML, API могут использовать другие форматы ответов, например неформатированный текст, HTM, буферы протоколов или файл CSV, в зависимости от предметно-ориентированных требований и соглашений. У каждого формата есть свои преимущества и сферы применения, от эффективности и производительности до удобочитаемости и адаптивности.

Формат JSON приобрел популярность в веб-разработке благодаря своей простоте, удобочитаемости и легкости в использовании. К счастью, рассматриваемый сервис тоже использует для обмена данными эту модель.



Настройка окружения и разработка

Чтобы настроить окружение на MQL5 для использования интерфейсов API в формате JSON, нужно выполнить несколько шагов.

MQL5 — язык программирования для создания торговых роботов, технических индикаторов, скриптов и библиотек функций для торговой платформы MetaTrader 5.

Вот общее руководство по настройке окружения для работы с интерфейсами API в формате JSON на MQL5:

  1. Понимание основ MQL5. Убедитесь, что хорошо понимаете основы языка программирования MQL5, а также базовые концепции трейдинга и финансовых рынков. Ознакомьтесь с Документацией MQL4 и Српавочником MQL5,чтобы освоить синтаксис и функции языка.
  2. Выберите библиотеку JSON. MQL5 не имеет встроенной поддержки парсинга JSON, поэтому придется использовать стороннюю библиотеку. Эти библиотеки можно найти на таких форумах, как MQL5 Community или GitHub. JSON Serialization и JSON Parser.
  3. Скачайте и установите библиотеку JSON. Загрузите выбранную библиотеку JSON и следуйте предоставленным библиотекой инструкциям по установке. Обычно это предполагает размещение файла библиотеки (mqh или mq5) в папке Include установки MetaTrader.
  4. Добавьте библиотеку в свой код. С помощью директивы #include включите библиотеку JSON в начало своего MQL-скрипта или советника (Expert Advisor):
  5. //Use this type of file include if the file is in MQL include follder
    #include <JAson.mqh>
    
    // Use this type of file include If this file is next to your EA file/follder
    #include "JAson.mqh" 
  6. Выполните HTTP-запросы. Для взаимодействия с API в JSON понадобится сделать HTTP-запросы. Популярные варианты: WinHTTP или WebRequest. Если вам нужен другой тип использования HTTP, загрузите и включите библиотеку HTTP в соответствии со своими потребностями.
  7. Сохраните ответ HTTP в файл. Поскольку большинство таких API ограничены по количеству запросов и это ограничение может вас беспокоить, лучше сохранять запрошенные данные в файл и использовать наш сохраненный файл вместо неоднократных ненужных запросов.
  8. Выполните анализ (парсинг) ответов JSON. Получив ответ от API, воспользуйтесь библиотекой JSON для парсинга данных JSON. Конкретный синтаксис будет зависеть от используемой библиотеки.
  9. Комбинирование. После классификации данных JSON можно комбинировать нужные данные со своей программой в соответствии с их моделью, стратегией или типом.


Инструкция для кода функций API

Язык MQL5 предлагает функцию WebRequest для HTTP-запросов, позволяя взаимодействовать с API.

Подробнее о документации Webrequest > Webrequest и Обмен данными HTTP

Ниже — пример MQL-кода для запроса данных JSON из адреса API с использованием метода GET:

// Required variables
string cookie=NULL, headers="", apikey="your api key",
value1="value 1", value2="value 2";
char post[],result[];
int res;
string URL   =  "https://www.example.com/API?apikey="+apikey+"&data1=value1&data2="+value2; // Rest API address

ResetLastError(); // Reset ast error
// HTTP request via MQL Webrequest, GET method with apikey, value1, and value2 and 2000 millisecond timeout 
res=WebRequest("GET", URL, cookie, NULL, 2000, post, 0, result, headers);
if(res==-1) // WebRequest error handling
 {
    int error =  GetLastError();
    if(error==4060) Print("Webrequest Error ",error);
    else if(error==5203) Print("HTTP request failed!");
    else Print("Unknow HTTP request error("+string(error)+")! ");
    LastHTTPError=error;
 }
else if (res==200) // The HTTP 200 status response code indicates that the request has succeeded
 {
    Print("HTTP request successful!");

    // Use CharArrayToString to convert HTTP result array to a string
    string HTTP_Result = CharArrayToString(result, 0, 0, CP_UTF8); 
    Print(HTTP_Result);      

 }

Этот код отправляет запрос GET на указанный URL-адрес API, демонстрируя простоту интеграции вызовов API в MQL4.



Пример применения. Успешный советник на MQL4 с доступом к данным API

Как использовать API данных валютных рынков Ziwox для создания системы автоматической торговли с помощью фундаментальных данных и данных прогнозов ИИ в реальном времени

В этой статье мы рассмотрим способы использования API данных валютных рынков Ziwox для разработки инструментов на основе фундаментальных данных и данных в реальном времени на языке MetaQuotes Language (MQL). Об их API много информации, но мы выбрали для своего проекта Прогноз ИИ.

Согласно Ziwox, система прогнозирования на базе ИИ в их терминале основана на агрегации таких данных, как новости, сведения из экономического календаря, процентные ставки и их изменения, денежная и экономическая политика центральных банков, рыночные настроения, устойчивости валют на рынке, данные о вовлеченности трейдеров и информация о розничных трейдерах. В результате происходит анализ всего рынка, и этот прогноз можно использовать как ценные данные.

Рассмотрим процессы получения данных API, сохранения данных JSON в файл, парсинга ответов JSON и использования этой информации для создания автоматического советника.

Наш план: создать советник, использовать простую стратегию на основе скользящих средних в качестве технического сигнала и торговать, если прогноз ИИ находится в нашем направлении как ИИ-фильтр.

Сделаем все, что в наших силах.


Шаг 1. Регистрация и генерация ключа API

Чтобы приступить к использованию Ziwox Forex Data API, выполните следующие действия:

1. Зарегистрируйтесь в терминале Ziwox ЗДЕСЬ

Ziwox Sign UP 

2. Заполните форму своими данными, ознакомьтесь с условиями и политикой, примите их, нажмите на “Я не робот” и затем на “Создать новую учетную запись”.

3. На ваш почтовый ящик отправлено письмо для подтверждения. Подтвердите свой электронный адрес.

3. Войдите в свою учетную запись здесь, перейдите на страницу профиля и вкладку API здесь и сгенерируйте свой ключ API, кликнув на зеленой кнопке Generate

Ziwox API generate

4. Теперь, сгенерировав ключ API, вы получаете доступ к данным API Ziwox. Скопируйте этот сгенерированный код API для использования в нашем проекте.

Ziwox API Key


Шаг 2. Понимание структуры API

Структура ссылки API следующая:

https://ziwox.com/terminal/services/API/V1/fulldata.php?expn=ziwoxuser&apikey={API_KEY}&apitype={REQUEST_TYPE}&pair={PAIR}

  • {API_KEY} — ваш уникальный ключ API из последнего шага
  • {REQUEST_TYPE} — формат ответа, JSON или текстовый.
  • {PAIR} — желаемая валютная пара в стандартном формате, без префикса или суффикса, например EURUSD, USDJPY, GBPUSD, XAUUSD, WTI…


Шаг 3. Проверка структуры вашего API

Теперь нам нужно проверить структуру ссылок API и запросить у Ziwox API образец. Просто используйте ссылку API из шага 2, отредактируйте параметры, указав свои, откройте браузер, введите ссылку API в адресной строке и нажмите на ввод.

При правильном редактировании ссылки API в ответе HTTP увидим следующее:

Ziwox API response


Для неправильного ключа API вы получите следующий ответ об ошибке:

{
"status": "error",
"desc": "invalid api key"
}

или, если вы неправильно введете имя актива, можно увидеть такой ответ:

{
"status": "error",
"desc": "invalid asset name!!"
}


Шаг 4. Реализовать функцию HTTP запроса API 

При успешном выполнении шага 3 мы готовы реализовать функцию для автоматизации этой части. Проверьте этот код:

datetime LastWebRequest = 0; // use this datetime var for limit failed request API

bool GetAPI(string symbolname, string apikey, string filename)

  {
   Print("Get API Update");
   bool NeedToUpdate =   false;

   // Check if the API data file available
   if(FileGetInteger(filename,FILE_EXISTS,true)>=0)
     {
      // Check the latest update time from file modify date time
      if(TimeLocal()-(datetime)FileGetInteger(filename,FILE_MODIFY_DATE,true)>900) // update data every 15 min becasue of API call rate limitation
         NeedToUpdate  = true;
     }
   else
      NeedToUpdate  =  true;


   if(NeedToUpdate && TimeLocal()-LastWebRequest>300)   // retry failed API request every 5 min to avoid firewall IP block
     {
      string   cookie=NULL,headers;
      char     post[],result[];
      int      res;
      string   URL   =  "https://www.ziwox.com/terminal/services/API/V1/fulldata.php?expn=ziwoxuser&apikey="+apikey+"&apitype=json&pair="+symbolname;
      ResetLastError();
      int timeout=5000;
      res=WebRequest("GET", URL, cookie, NULL, timeout, post, 0, result, headers);
      if(res==-1)
        {
         LastWebRequest    =  TimeLocal();
         int error         =  GetLastError();
         if(error==4060)
            Print("API data Webrequest Error ",error, " Check your webrequest on Metatrader Expert option.");
         else  if(error==5203)
               Print("HTTP request for "+symbolname+" Data failed!");
            else
               Print("Unknow HTTP request error("+string(error)+")! "+symbolname+" Data");
         return(false);
        }
      else
         if(res==200)
           {
            LastWebRequest =  TimeLocal();
            string HTTPString = CharArrayToString(result, 0, 0, CP_UTF8);
            Print("HTTP request for "+symbolname+" Data successful!");
            Print(HTTPString);
	    
            if (StringFind(HTTPString,"invalid api key",0)!=-1) {
               Alert("invalid api key");
               return(false);
            }
            // Store the API data into a common folder file
            int filehandle=FileOpen(filename,FILE_READ|FILE_SHARE_READ|FILE_WRITE|FILE_SHARE_WRITE|FILE_BIN|FILE_COMMON);
            if(filehandle!=INVALID_HANDLE)
              {
               FileWriteArray(filehandle,result,0,ArraySize(result));
               FileClose(filehandle);
              }
           }
     }
   return(true);
  }

В качестве вводных данных от вас эта функция принимает ключ аутентификации API (apikey), название актива (symbolname) и имя файла (filename). Для подготовки ссылки запроса API она встраивает "apikey" и "symbolname" в URL-адрес.

Затем она использует функцию Webrequest для выполнения HTTP-запроса, примерно как на предыдущем шаге, и, наконец, получает ответ от сервера и помещает соответствующую информацию ф файл с именем "filename".

Вызовем функцию API следующим образом:

string APIfilename =  symbolname+"_API_Data.json"; // API store file name
string APIKey = "76thfd67a6f867df7"; // Our unic API Key, change it with your API Key
string SymbolRequest = "EURUSD"; // Symbol request, without prefix or suffix
string APIJSON[];
bool APIGET = GetAPI(SymbolRequest, APIKey,  APIfilename);


Шаг 5. Парсинг данных JSON

Как вы помните из шага 3, полученные от API данные содержат массив данных. Полную характеристику этих данных можно видеть в таблице ниже.

Имя объекта JSON Тип данных Описание
Символ string Возвращает то же имя актива или символа
Цена Last буфера Цена Last актива
цифры буфера Цифры стоимости актива
База string Базовое название пары
Котировка string Котировочное название пары
Базовый фундаментальный сдвиг string Фундаментальный сдвиг или фундаментальный прогноз базовой валюты. Он может быть бычьим или медвежьим
Базовая фундаментальная мощность string Базовая фундаментальная мощность сдвига. Может быть слабой (Week), умеренной (Moderate) и сильной (Strong)
Фундаментальный сдвиг котировки string Фундаментальный сдвиг или фундаментальный прогноз валюты котировки. Может быть бычьим или медвежьим
Фундаментальная мощность котировки string Базовая фундаментальная мощность сдвига котировки. Может быть слабой (Week), умеренной (Moderate) и сильной (Strong)
Фундаментальный сдвиг string Фундаментальный сдвиг актива или долгосрочный фундаментальный прогноз активов. Бычий или медвежий
Фундаментальная мощность string Фундаментальная мощность актива. Слабая (Weak), умеренная (Moderate) или сильная (Strong)
Фундаментальный стимул string То же, что и фундаментальный сдвиг актива. Это число, если оно равно 50, тренд нейтральный, выше 50 — бычий, а ниже 50 — медвежий
Бычий прогноз ИИ Проценты Пррогноз бычьего движения стоимости актива. Чем больше число, тем более бычий тренд
Медвежий прогноз ИИ Проценты Прогноз медвежьего движения стоимости актива. Чем больше число, тем более медвежий тренд
Розничное соотношение Long Проценты Процент розничных трейдеров, торгующих Long
Розничный лот Long буфера Лот Long у розничных трейдеров (объем ордеров)
Розничные длинные позиции буфера Количество позиций Long у розничных трейдеров
Розничное соотношение Short Проценты Процент розничных трейдеров, торгующих Short
Розничный лот Short буфера Лот Short у розничных трейдеров (объем ордеров)
Розничные короткие позиции буфера Количество позиций Short у розничных трейдеров
Базовые COT NET буфера Чистая позиция COT базовой валюты
Изменение базовой COT буфера Изменения (еженедельные) чистой позиции COT базовой валюты
COT NET котировки буфера Чистая позиция COT валюты котировки
Изменение COT котировки буфера Изменения (еженедельные) чистой позиции COT валюты котировки
Коэффициент COT chng буфера Коэффициент изменения чистых позиций крупных спекулянтов. Положительное число = настроения Long, отрицательное число = настроения Short
Настроения в оценке рисков string Настроения рынка в оценке рисков: склонность к риску (Risk-ON), неприятие риска (Risk-OFF) или индифференцированная оценка (MIX)
Тренд D1 string Технические данные, дневной тренд, тренд покупки или продажи
D1 RSI буфера Данные индикатора, дневное значение индикатора RSI
D1 Stoch буфера Данные индикатора, дневное значение индикатора Stochastic
cci числа Значения индикатора CCI и
сигнал cci string Сигнал индикатора CCI
поддержки числа Уровни поддержки актива
сопротивление числа Уровни сопротивления актива
пивот числа Точка или уровни разворота актива
Значение VIX буфера Значение индекса волатильности, VIX
Направление VIX буфера Направление настроений VIX: вверх = страх и рискованный рынок, вниз = жадный рынок
Стимул VIX к покупке буфера Положительное число = жадный рынок 
Стимул VIX к продаже буфера Отрицательное число = страх и рискованный рынок
Базовая облигация буфера Значение доходности облигации базовой валюты
Изм. базовой облигации буфера Изменение доходности облигации базовой валюты
Облигация котировки буфера Значение доходности облигации валюты котировки
Изм. облигации котировки буфера Изменение доходности облигации в валюте котировки
US10Y буфера Значение доходности 10-летних облигаций США
Изм. US10Y буфера Изменение значения H1 US10Y
Стимул доходности буфера Положительное число в пользу базовой валюты, отрицательное в пользу валюты котировки   
Разрешить торговлю булевы Предложение Ziwox: торговать или лучше прекратить торговлю
Причина остановки Строка Если предлагается не торговать, то причину можно увидеть здесь.
riskriversal буфера Значение разворота риска для этого актива. Определить значение PUT/CALL
cesi буфера Значение CESI
yielddiff буфера Доходность базовой валюты - Доходность валюты котировки 
banksposition буфера Соотношение позиций банковских учреждений
macrofundamental буфера Макроэкономическое значение: положительное число означает фактор бычьего тренда для актива, а отрицательное — медвежьего
longtermsentiment буфера Долгосрочные настроения в отношении актива, основанные на экономике, политике и т. д.
seasonal Проценты Возможность роста или снижения актива в соответствии с сезонными данными


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

Функция будет примерно такой:

#include "JAson.mqh"  // include the JSON librery in our project
CJAVal JsonValue;


void JsonDataParse(string filename, string &_APIJSON[])

  {
   bool     UpdateData =   false;
   for (int arraIn=0; arraIn<ArraySize(APIJSON); arraIn++) APIJSON[arraIn]="";


   if(FileGetInteger(filename,FILE_EXISTS,true)>=0)
     {
      int   FileHandle =FileOpen(filename,FILE_READ|FILE_SHARE_READ|FILE_WRITE|FILE_SHARE_WRITE|FILE_BIN|FILE_COMMON);
      char  jsonarray[];
      FileReadArray(FileHandle,jsonarray);
      FileClose(FileHandle);

      JsonValue.Clear();
      JsonValue.Deserialize(CharArrayToString(jsonarray, 0, 0, CP_UTF8));


      _APIJSON[0]   =   JsonValue[0]["Symbol"].ToStr();
      _APIJSON[1]   =   JsonValue[0]["Fundamental Bias"].ToStr();
      _APIJSON[2]   =   JsonValue[0]["Fundamental Power"].ToStr();
      _APIJSON[3]   =   JsonValue[0]["AI Bullish Forecast"].ToStr();
      _APIJSON[4]   =   JsonValue[0]["AI Bearish Forecast"].ToStr();
      _APIJSON[5]   =   JsonValue[0]["Retail Long Ratio"].ToStr();
      _APIJSON[6]   =   JsonValue[0]["Retail Short Ratio"].ToStr();
      _APIJSON[7]   =   JsonValue[0]["Retail Short Lot"].ToStr();
      _APIJSON[8]   =   JsonValue[0]["Retail Short pos"].ToStr();
      _APIJSON[9]   =   JsonValue[0]["Base COT NET"].ToStr();
      _APIJSON[10]  =   JsonValue[0]["Base COT change"].ToStr();
      _APIJSON[11]  =   JsonValue[0]["Quote COT NET"].ToStr();
      _APIJSON[12]  =   JsonValue[0]["Quote COT change"].ToStr();
      _APIJSON[13]  =   JsonValue[0]["COT chng Ratio"].ToStr();
      _APIJSON[14]  =   JsonValue[0]["Risk Sentiment"].ToStr();
     }
  }

И вызовем функцию JSON примерно так:

string APIfilename =  symbolname+"_API_Data.json"; // API store file name
string API_DATA[]; // define an array variable to store API details

JsonDataParse( APIfilename,API_DATA);


Шаг 6. Создание простой стратегии пересечения скользящих средних

Используя извлеченные данные, сохраненные в переменной “APIJSON”, теперь можно создавать стратегии автотрейдинга и комбинировать нашу стратегию с системой прогнозирования на основе ИИ. Вот базовый пример использования данных в советнике:

Можете выбрать любую стратегию по своему вкусу. Но в этой статье мы попытаемся выбрать простую, потому что наша цель в данном случае — направить и обучить вас способам использования такого инструмента в собственных проектах, чтобы сделать их на шаг лучше.

Стратегия пересечения скользящих средних — популярный метод, который трейдеры используют для определения потенциальных сигналов о покупке и продаже.

Эта стратегия использует два скользящих средних. Краткосрочное и долгосрочное для определения рыночного тренда.

Когда краткосрочное скользящее среднее пересекает снизу вверх долгосрочное, это — сигнал к покупке, а когда пересекает сверху вниз — к продаже.

Займемся этим:

shortMA  = iMA(Symbol(), 0, shortMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
longMA   = iMA(Symbol(), 0, longMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);


// Check for crossover signals
if ( int(APIJSON[3])>=60 ) // if bullish forecast is higher than 60%
   if (shortMA > longMA)   // BUY trend 
   { 
      if (OrdersTotal() == 0) {
         ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, 0, 0, "Buy Order", 0, 0, Green);
         if (ticket < 0) Print("Error opening buy order: ", GetLastError());
      }
   }

if ( int(APIJSON[4])>=60 ) // if bearish forecast is higher than 60%
   if (shortMA < longMA)   // Sell trend
   {
      if (OrdersTotal() == 0) 
      {
         ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 3, 0, 0, "Sell Order", 0, 0, Red);
         if (ticket < 0) Print("Error opening sell order: ", GetLastError());
      }
   }


Шаг 7. Использование данных JSON для фильтрации сигналов

Для улучшения стратегии пересечения скользящих средних используем данные JSON, а для фильтрации сигналов — коэффициент прогнозирования ИИ из API Ziwox.

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

Опираясь на организованные на шаге 4 данные JSON, прогноз ИИ, процент быков находится в 3-м (третьем) элементе нашего массива, а медвежий прогноз — в четвертом элементе.

Код может выглядеть так:

void OnTick()
  {
   if (!APIOK) return;
   double   shortMA, longMA;
   long     ticket = -1;

   if(IsNewCandle())
     {
      shortMA  = iMA(Symbol(), 0, shortMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
      longMA   = iMA(Symbol(), 0, longMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
      
      // Check for crossover signals
      if ( int(APIJSON[3])>=60 ) // if bullish forecast is higher than 60%
         if (shortMA > longMA)   // BUY trend 
         { 
            if (OrdersTotal() == 0) {
               ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, 0, 0, "Buy Order", 0, 0, Green);
               if (ticket < 0) Print("Error opening buy order: ", GetLastError());
            }
         }
      if ( int(APIJSON[4])>=60 ) // if bearish forecast is higher than 60%
         if (shortMA < longMA)   // Sell trend
         {
            if (OrdersTotal() == 0) 
            {
               ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 3, 0, 0, "Sell Order", 0, 0, Red);
               if (ticket < 0) Print("Error opening sell order: ", GetLastError());
            }
         } 
     }
  }


Заключение

Интеграция данных API с MQL4 позволяет трейдерам создавать более адаптивные и управляемые данными советники. Используя информацию из внешних источников в режиме реального времени, трейдеры могут совершенствовать свои стратегии и принимать более обоснованные торговые решения в постоянно меняющихся условиях рынка. Можно получить доступ к данным, выходящим за рамки необработанных рыночных цен. Такой подход позволяет сочетать технический и фундаментальный анализ, повышая эффективность торговых стратегий.

Ниже — окончательный код, готовый к загрузке.

Буду рад ответить на вопросы, предложения и критику.

Всего наилучшего и удачной торговли.

Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/14108

Прикрепленные файлы |
APIExpert.mq4 (18.77 KB)
JAson.mqh (30.59 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (21)
Edgar Akhmadeev
Edgar Akhmadeev | 21 янв. 2025 в 13:18
Ney Borges #:
При необходимости можно использовать библиотеку JAson.mqh, которая находится в оригинальном коде нашего компаньона.

Как ужасно работает гугл-переводчик.

Без библиотеки JAson, конечно, не будет работать.

Библиотека не в его коде, а здесь, и автор это указал.

Ney Borges
Ney Borges | 21 янв. 2025 в 19:24
Sara Sabaghi #:

Да, я полностью это понимаю. Кроме того, мы обязаны использовать этот стандарт, поскольку почти все поставщики финансовых данных используют этот метод.

Ney Borges #:
Здравствуйте, вот оно, то, о чем я просил, я разместил в сообществе mql5 =.

Версия для MQL5 METATRADER 5 Я внес изменения в код, чтобы он работал в Metatrader 5. Также были внесены изменения в кодировку для улучшения условий в текущей коммерческой ситуации. Все изменения были направлены на адаптацию кода к Metatrader 5. Это функционально. Просто скачайте этот файл и запустите его. При необходимости можно использовать библиотеку JAson.mqh, которая находится в оригинальном коде нашего компаньона. Меня зовут Ней Борхес. Я из Бразилии, штат Гояс, город Калдас-Новас, посреди лесов Бразилии. Было очень трудно учиться в одиночку, без чьей-либо помощи, но здесь, в сообществе, я многому научился. Спасибо.

Версия для MQL5 METATRADER 5 Я внес изменения в код, чтобы он работал в Metatrader 5. Также были внесены изменения в кодировку для улучшения условий в текущей коммерческой ситуации. Все изменения были направлены на адаптацию кода к Metatrader 5. Это функционально. Просто скачайте этот файл и запустите его. При необходимости можно использовать библиотеку JAson.mqh, которая находится в оригинальном коде нашего компаньона. Меня зовут Ней Борхес. Я из Бразилии, штат Гояс, город Калдас-Новас, посреди лесов Бразилии. Было очень трудно учиться в одиночку, без чьей-либо помощи, но здесь, в сообществе, я многому научился. Спасибо.

Бразилия - Гояс - Калдас-Новас - Ней Борхес

Fiz algumas correçoes ao codigo para funcionar no MQL5 gostaria que por gentilesa verificasse e retornar, obrigado - Sara Sabaghi

//+------------------------------------------------------------------+
//| Ney Borges versão mql5 de ZIWOX API and Technical Strategy.mq5 |
//|                                        Copyright 2024, ssabbaghi |
//|                          https://www.mql5.com/en/users/ssabbaghi |
//+------------------------------------------------------------------+
#property   copyright   "Sara Sabbaghi"
#property   link        "https://www.mql5.com/en/users/ssabbaghi"
#property   version     "1.0"
#property   strict
#property   description "Expert com funções de rede para ZIWOX API"

// Bibliotecas
#include <JAson.mqh>
CJAVal JsonValue;

// Propriedades do Expert para permitir funções de rede
//#property script_show_inputs
//#property script_show_confirm

//---- input parameters
input    string      APIKey         =  "sua Key aqui xxxxxxxx";      // Your unique API key
input    string      SymbolPrefix   =  "";      // Your Broker account symbol Prefix
input    string      SymbolSuffiex  =  "m";      // Your Broker account symbol Suffix
input    int         shortMAPeriod  =  50;      // Slow MA Period
input    int         longMAPeriod   =  200;     // Fast MA Period
input    double      Lots           =  0.01;    // Static Order volume
input    double      BullishThreshold = 60.0;   // Threshold for bullish forecast
input    double      BearishThreshold = 60.0;   // Threshold for bearish forecast
input    int         APICallInterval = 300;     // Interval between API calls in seconds (5 minutes)

string   OBJPREFIX      =  "ZXAPI",
         SymbolRequest  =  "",
         APIJSON[];
bool     APIOK          =  false;
datetime LastAPICallTime = 0; // Armazena o tempo da última chamada à API

//+------------------------------------------------------------------+
//| Função para testar conexão HTTP                                  |
//+------------------------------------------------------------------+
bool TestHTTPConnection()
{
   string cookie=NULL,headers;
   char post[],result[];
   string url="https://www.ziwox.com";
   
   ResetLastError();
   int timeout=5000; 
   
   int res=WebRequest("GET",url,cookie,NULL,timeout,post,0,result,headers);
   
   if(res==-1)
   { 
      int error=GetLastError();
      string msg = "Falha ao conectar, erro "+IntegerToString(error);
      
      // Se for erro de permissão, mostra mensagem específica
      if(error==4014)
         msg = "Adicione "+url+" em Ferramentas -> Opções -> Expert Advisors -> Permitir WebRequest";
         
      Print("DEBUG: ", msg);
      return(false);
   }
   
   Print("DEBUG: Conexão HTTP testada com sucesso");
   return(true);
}

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   Print("=== Iniciando Expert Advisor ===");
   
   // Verifica configurações básicas
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {
      Print("AVISO: Algorithmic Trading não está permitido");
      // Continua mesmo assim
   }
   
   if(!TerminalInfoInteger(TERMINAL_CONNECTED))
   {
      Print("AVISO: Terminal não está conectado à internet");
      // Continua mesmo assim
   }
   
   // Configura o EA
   EventSetTimer(30);
   ArrayResize(APIJSON, 15);
   SymbolRequest = PureSymbol(Symbol(), SymbolSuffiex, SymbolPrefix);
   
   // Prepara e mostra a URL que será usada
   string cleanSymbol = SymbolRequest;
   StringReplace(cleanSymbol, "m", "");
   string apiUrl = StringFormat("https://www.ziwox.com/terminal/services/API/V1/fulldata.php?expn=ziwoxuser&amp;apikey=%s&apitype=json&pair=%s", 
                              APIKey, cleanSymbol);
   
   Print("URL configurada: ", apiUrl);
   Print("IMPORTANTE: Adicione a URL https://www.ziwox.com em:");
   Print("Ferramentas -> Opções -> Expert Advisors -> Permitir WebRequest");
   
   Comment("Iniciando EA...\n",
           "URL que será usada:\n",
           apiUrl,
           "\n\nIMPORTANTE: Configure a URL nas opções do Expert Advisor");
   
   // Testa conexão HTTP, mas não falha se der erro
   if(!TestHTTPConnection())
   {
      Print("AVISO: Teste de conexão HTTP falhou");
      Print("O EA continuará tentando conectar...");
      // Continua mesmo assim
   }
   
   Print("=== Inicialização concluída ===");
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");
   ObjectsDeleteAll(0);
}

//+------------------------------------------------------------------+
//| Expert tick function    OnTick()                                 |
//+------------------------------------------------------------------+
void OnTick()
{
   if (!APIOK) return;
   
   double shortMA, longMA;
   MqlTradeRequest request = {};
   MqlTradeResult result = {};
   
   if (IsNewCandle())
   {
      shortMA = iMA(Symbol(),PERIOD_CURRENT, shortMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
      longMA = iMA(Symbol(),PERIOD_CURRENT, longMAPeriod, 0, MODE_SMA, PRICE_CLOSE);

      // Analisando dados JSON para decisões de negociação
      double aiBullishForecast = StringToDouble(APIJSON[3]); // Previsão de alta
      double aiBearishForecast = StringToDouble(APIJSON[4]); // Previsão de baixa

      // Check for crossover signals
      if (aiBullishForecast >= BullishThreshold && shortMA > longMA) // Se a previsão de alta for maior que o limite
      {
         if (OrdersTotal() == 0) {
            request.action = TRADE_ACTION_DEAL;
            request.symbol = _Symbol;
            request.volume = Lots;
            request.type = ORDER_TYPE_BUY;
            request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
            request.deviation = 3;
            request.magic = 123456;
            request.comment = "Buy Order";
            request.type_filling = ORDER_FILLING_FOK;
            
            if(!OrderSend(request, result))
               Print("Error opening buy order: ", GetLastError());
         }
      }
      if (aiBearishForecast >= BearishThreshold && shortMA < longMA) // Se a previsão de baixa for maior que o limite
      {
         if (OrdersTotal() == 0) {
            request.action = TRADE_ACTION_DEAL;
            request.symbol = _Symbol;
            request.volume = Lots;
            request.type = ORDER_TYPE_SELL;
            request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
            request.deviation = 3;
            request.magic = 123456;
            request.comment = "Sell Order";
            request.type_filling = ORDER_FILLING_FOK;
            
            if(!OrderSend(request, result))
               Print("Error opening sell order: ", GetLastError());
         }
      }
   }
}

//+------------------------------------------------------------------+
//| Função para verificar se a URL está permitida                    |
//+------------------------------------------------------------------+
bool IsURLAllowed()
{
   string url = "https://www.ziwox.com";
   string cookie=NULL, headers;
   char post[], result[];
   ResetLastError();
   
   int res = WebRequest("GET", url, cookie, NULL, 5000, post, 0, result, headers);
   
   if(res == -1)
   {
      int error = GetLastError();
      if(error == 4014)
      {
         Comment("ATENÇÃO: URL não permitida\n",
                 "1. Vá em Ferramentas -> Opções -> Expert Advisors\n",
                 "2. Marque 'Permitir WebRequest para as URLs listadas abaixo'\n",
                 "3. Adicione a URL: ", url, "\n",
                 "4. Clique em OK");
         return false;
      }
   }
   return true;
}

//+------------------------------------------------------------------+
//| Expert OnTimer function                                          |
//+------------------------------------------------------------------+
void OnTimer()
{
   // Verifica se a URL está permitida antes de fazer a chamada
   if(!IsURLAllowed())
   {
      Print("DEBUG: URL não está permitida. Aguardando configuração...");
      return;
   }

   if (TimeCurrent() - LastAPICallTime >= APICallInterval)
   {
      string APIfilename = SymbolRequest + "_API_Data.json";
      
      // Prepara a URL para mostrar no comentário
      string cleanSymbol = SymbolRequest;
      StringReplace(cleanSymbol, "m", "");
      string apiUrl = StringFormat("https://www.ziwox.com/terminal/services/API/V1/fulldata.php?expn=ziwoxuser&amp;apikey=%s&apitype=json&pair=%s", 
                                 APIKey, cleanSymbol);
      
      // Mostra que está fazendo a chamada
      Comment("Fazendo chamada à API...\n",
              "URL: ", apiUrl,
              "\n\nAguarde...");
      
      APIOK = GetAPI(SymbolRequest, APIKey, APIfilename);
      
      if (APIOK) {
         JsonDataParse(APIfilename, APIJSON);
         Comment("=== API OK ===\n",
                 "URL: ", apiUrl, "\n",
                 "Última atualização: ", TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS), "\n",
                 "\nDados recebidos:",
                 "\nSymbol: ", APIJSON[0],
                 "\nÚltimo Preço: ", APIJSON[1],
                 "\nViés Fundamental: ", APIJSON[2],
                 "\nPrevisão de Alta: ", APIJSON[3], "%",
                 "\nPrevisão de Baixa: ", APIJSON[4], "%",
                 "\nPosições Compradas: ", APIJSON[5],
                 "\nPosições Vendidas: ", APIJSON[6],
                 "\nTendência D1: ", APIJSON[7],
                 "\nRSI D1: ", APIJSON[8],
                 "\nPermitido Operar: ", APIJSON[9]
                 );
      } else {
         Comment("=== FALHA NA API ===\n",
                 "URL tentada: ", apiUrl, "\n",
                 "Hora: ", TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS), "\n",
                 "\nVerifique:",
                 "\n1. Se a URL está permitida em Ferramentas -> Opções -> Expert Advisors -> WebRequest",
                 "\n2. Se sua conexão com a internet está funcionando",
                 "\n3. Se o símbolo está correto"
                 );
      }

      LastAPICallTime = TimeCurrent();
   }
}

//+------------------------------------------------------------------+
//| Função para verificar se é um novo candle                       |
//+------------------------------------------------------------------+
bool IsNewCandle()
{
   static datetime lastCandleTime = 0;
   datetime currentCandleTime = iTime(Symbol(), 0, 0);
   if (currentCandleTime != lastCandleTime)
   {
      lastCandleTime = currentCandleTime;
      return true;
   }
   return false;
}

//+------------------------------------------------------------------+
//| Pure symbol function                                             |
//+------------------------------------------------------------------+
string PureSymbol(string symbol, string suffiex, string prefix)
{
   string puresymbol = symbol;
   if (prefix != "" || suffiex != "")
   {
      StringReplace(puresymbol, suffiex, "");
      StringReplace(puresymbol, prefix, "");
   }
   return puresymbol;
}

//+------------------------------------------------------------------+
//| Função para verificar configuração do WebRequest                 |
//+------------------------------------------------------------------+
bool CheckWebRequestSettings()
{
   if(!TerminalInfoInteger(TERMINAL_DLLS_ALLOWED))
   {
      Print("ERRO: DLLs não estão permitidas!");
      return false;
   }
   
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {
      Print("ERRO: Algorithmic Trading não está permitido!");
      return false;
   }
   
   if(!MQLInfoInteger(MQL_DLLS_ALLOWED))
   {
      Print("ERRO: DLLs não estão permitidas para este Expert!");
      return false;
   }
   
   return true;
}

//+------------------------------------------------------------------+
//| Função para verificar conexão com o servidor                     |
//+------------------------------------------------------------------+
bool CheckServerConnection()
{
   int socket = SocketCreate();
   
   if(socket != INVALID_HANDLE)
   {
      // Tenta conectar ao servidor da ZIWOX (porta 80 para HTTP)
      if(SocketConnect(socket, "www.ziwox.com", 80, 1000))
      {
         Print("DEBUG: Conexão com servidor testada com sucesso");
         // Verifica se está realmente conectado
         if(SocketIsConnected(socket))
         {
            SocketClose(socket);
            return true;
         }
      }
      else
      {
         Print("DEBUG: Falha ao conectar com o servidor: ", GetLastError());
      }
      SocketClose(socket);
   }
   else
   {
      Print("DEBUG: Falha ao criar socket: ", GetLastError());
   }
   return false;
}

//+------------------------------------------------------------------+
//| Função para obter dados da API                                   |
//+------------------------------------------------------------------+
bool GetAPI(string symbolname, string apikey, string filename)
{
   if(!TestHTTPConnection())
   {
      Print("DEBUG: Falha no teste de conexão HTTP");
      return false;
   }

   string headers = "Content-Type: application/json\r\nAccept: application/json\r\n";
   char post[], result[];
   string cookie=NULL;
   int res;
   
   // Remove o sufixo 'm' do símbolo para a API
   string cleanSymbol = symbolname;
   StringReplace(cleanSymbol, "m", "");
   
   string URL = "https://www.ziwox.com/terminal/services/API/V1/fulldata.php";
   string params = StringFormat("?expn=ziwoxuser&apikey=%s&apitype=json&pair=%s", 
                              apikey, cleanSymbol);
   
   Print("DEBUG: Preparando requisição...");
   Print("DEBUG: URL completa: ", URL + params);
   
   URL = URL + params;
   
   string body = StringFormat("{\"apikey\":\"%s\",\"pair\":\"%s\"}", apikey, cleanSymbol);
   StringToCharArray(body, post, 0, WHOLE_ARRAY, CP_UTF8);
   
   Print("DEBUG: Body da requisição: ", body);
   
   // Tenta fazer a requisição
   Print("DEBUG: Iniciando WebRequest...");
   res = WebRequest("GET", URL, cookie, NULL, 5000, post, 0, result, headers);
   Print("DEBUG: Código de resposta WebRequest: ", res);
   
   if(res == -1)
   {
      int error = GetLastError();
      Print("DEBUG: GetLastError retornou: ", error);
      return false;
   }
   
   if(res != 200)
   {
      Print("DEBUG: Resposta HTTP diferente de 200: ", res);
      return false;
   }
   
   string response = CharArrayToString(result, 0, WHOLE_ARRAY, CP_UTF8);
   
   // Remove a tag <pre> da resposta
   StringReplace(response, "<pre>", "");
   StringReplace(response, "</pre>", "");
   
   Print("DEBUG: Resposta recebida (primeiros 500 caracteres): ", StringSubstr(response, 0, 500));
   Print("DEBUG: Tamanho total da resposta: ", StringLen(response));
   
   if(StringFind(response, "invalid api key") >= 0)
   {
      Print("DEBUG: API Key inválida encontrada na resposta");
      Alert("Invalid API key");
      return false;
   }
   
   // Tenta salvar a resposta
   Print("DEBUG: Tentando salvar resposta no arquivo: ", filename);
   int filehandle = FileOpen(filename, FILE_WRITE|FILE_BIN|FILE_COMMON);
   if(filehandle != INVALID_HANDLE)
   {
      // Converte a resposta para array de caracteres
      char responseArray[];
      StringToCharArray(response, responseArray, 0, StringLen(response));
      
      // Salva no arquivo
      FileWriteArray(filehandle, responseArray);
      FileClose(filehandle);
      Print("DEBUG: Arquivo salvo com sucesso");
      return true;
   }
   
   Print("DEBUG: Falha ao salvar arquivo");
   return false;
}

//+------------------------------------------------------------------+
//| Função para analisar dados JSON                                   |
//+------------------------------------------------------------------+
void JsonDataParse(string filename, string &_APIJSON[])
{
   for (int arraIn = 0; arraIn < ArraySize(APIJSON); arraIn++) 
      APIJSON[arraIn] = "";

   if (FileGetInteger(filename, FILE_EXISTS, true) >= 0)
   {
      int FileHandle = FileOpen(filename, FILE_READ|FILE_BIN|FILE_COMMON);
      if(FileHandle != INVALID_HANDLE)
      {
         char jsonarray[];
         FileReadArray(FileHandle, jsonarray);
         FileClose(FileHandle);

         JsonValue.Clear();
         string jsonString = CharArrayToString(jsonarray, 0, WHOLE_ARRAY, CP_UTF8);
         Print("JSON Recebido: ", jsonString); // Debug
         
         if(JsonValue.Deserialize(jsonString))
         {
            _APIJSON[0] = JsonValue[0]["Symbol"].ToStr();
            _APIJSON[1] = JsonValue[0]["Last Price"].ToStr();
            _APIJSON[2] = JsonValue[0]["Base Fundamental Bias"].ToStr();
            _APIJSON[3] = JsonValue[0]["AI Bullish Forecast"].ToStr();
            _APIJSON[4] = JsonValue[0]["AI Bearish Forecast"].ToStr();
            _APIJSON[5] = JsonValue[0]["Retail Long Ratio"].ToStr();
            _APIJSON[6] = JsonValue[0]["Retail Short Ratio"].ToStr();
            _APIJSON[7] = JsonValue[0]["D1 Trend"].ToStr();
            _APIJSON[8] = JsonValue[0]["D1 RSI"].ToStr();
            _APIJSON[9] = JsonValue[0]["Allow To Trade"].ToStr();
            
            Print("Dados processados:");
            Print("Symbol: ", _APIJSON[0]);
            Print("Last Price: ", _APIJSON[1]);
Sara Sabaghi
Sara Sabaghi | 21 янв. 2025 в 20:33
Ney Borges #:

Fiz algumas correçoes ao codigo para funcionar no MQL5 gostaria que por gentilesa verificasse e retornar, obrigado - Sara Sabaghi

Привет, чувак

Спасибо, что поделился своим кодом. Да, я протестировал его. Он работает нормально

Ziwox Forex Data API

fxsaber
fxsaber | 22 янв. 2025 в 15:58
Nikolai Semko #:

Перешли на бинарник. Размер теперь тех же данных 1.2 Mb. Парсинг в нужные массивы структур теперь занимает 5 миллисекунд.

Что-то многовато у Вас. Здесь 12 мс, но данных 80 Mb.

BeeXXI Corporation
Nikolai Semko | 22 янв. 2025 в 16:55
fxsaber #:

Что-то многовато у Вас. Здесь 12 мс, но данных 80 Mb.

Не, там с парсингом все максимально оптимально. Просто структура данных на сервере очень неоптимальная, на что я не смог повлиять. На выходе парсинга 5 массивов структур, а на входе (в бинарнике) 2 массива структур. Т. е. 3 массива структур вложены в элементы 2х массивов структур. Поэтому пришлось копировать поэлементно. Единственное, с чем соврал, так это то, с JSON размером в 20 Мб перешли на бинарник размером не в 1.2 Мб, а 2.2 Мб
Разработка системы репликации (Часть 58): Возвращаемся к работе над сервисом Разработка системы репликации (Часть 58): Возвращаемся к работе над сервисом
После перерыва в разработке и улучшении сервиса, используемого для репликации/моделирования, сегодня мы возобновляем над ним работу. Теперь, когда мы отказались от использования таких ресурсов, как глобальные переменные терминала, нам придется полностью реструктурировать некоторые его части. Не волнуйтесь, этот процесс будет подробно объяснен, чтобы каждый мог следить за разработкой нашего сервиса.
Нейросети в трейдинге: Многоагентная система с концептуальным подтверждением (FinCon) Нейросети в трейдинге: Многоагентная система с концептуальным подтверждением (FinCon)
Предлагаем познакомиться с фреймворком FinCon, который представляет собой многоагентную систему на основе больших языковых моделей (LLM). Фреймворк использует концептуальное вербальное подкрепление для улучшения принятия решений и управления рисками, что позволяет эффективно выполнять разнообразные финансовые задачи.
От начального до среднего уровня: Переменные (I) От начального до среднего уровня: Переменные (I)
Многим начинающим программистам тяжело понять почему их код работает не так, как они ожидают. Существует множество моментов, которые делают код действительно функциональным. Это не просто набор разных функций и операций, который заставляет код работать. Сегодня я предлагаю вам научиться правильно создавать настоящий код, а не копировать и вставлять его фрагменты. Представленные здесь материалы имеют исключительно дидактический характер. Ни в коем случае нельзя рассматривать приложение ни с какой иной целью, кроме как для изучения и освоения представленных концепций.
Возможности Мастера MQL5, которые вам нужно знать (Часть 28): Сети GAN в контексте темпа обучения Возможности Мастера MQL5, которые вам нужно знать (Часть 28): Сети GAN в контексте темпа обучения
Темп обучения — это размер шага к цели обучения во многих алгоритмах машинного обучения. В статье мы изучим, какое влияние многочисленные форматы могут оказать на производительность генеративно-состязательной сети (Generative Adversarial Network, GAN) — разновидности нейронной сети, которую мы рассмотрели в одной из предыдущих статей.