Блог им. elektroyar |Ошибки в MQL5

Как-то раз решил перенести свой советник с МТ4 на МТ5. И все было по началу хорошо, пока не обнаружил странное поведение в коде. При помощи записи состояния всех переменных стратегий в лог я выяснил, что некоторые условия срабатывали тогда, когда не надо. И наоборот, некоторые условия не срабатывали.

Самый простой пример:

double a = 5;
double b = 10;

if (a > b) {

}

В любом языке программирования такое условие не выполнится. Но в MQL5 подобные условия иногда выполняются. И от чего это зависит — не понятно.

Тогда мне помогло лишь одно: я переехал с терминала МТ5 от брокера Альпари (он не хотел обновляться до свежей версии) на оригинальный МТ5 последней (на тот момент) версии. И это помогло, подобные баги исчезли. Менять что либо в коде было бесполезно.

И вот недавно я решился сделать заказ для знакомого. По началу все шло хорошо, но вот захотелось добавить асинхронное открытие и закрытие сделок. Казалось бы, что может быть проще?

Опустим такую деталь, что в очень удобном МТ5 нет специальной переменной в запросе, чтобы можно было однозначно судить о том, ответ на какой именно запрос открыть позицию пришел от сервера.



( Читать дальше )
  • обсудить на форуме:
  • MQL5

Блог им. elektroyar |Пошел сливать бабосики на бинарках

В общем, угрохав на исследования 2-3 года (не ну конечно за 2-3 года я еще успел сделать несколько безуспешных проектов инвесторов) я таки запустил наконец-то реальную торговлю сразу на двух брокерах бинарок.

Поковырявшись в 264 стратегиях я выяснил, что хорошо себя ведут стратегии, которые были изобретены еще 2 года назад. Ну то есть сильные закономерности существуют до сих пор и уверенно себя чувствуют. С тех пор конечно что-то было улучшено, но сами закономерности остались те же. Даже обидно, мог бы раньше запуститься.

В итоге решил убрать стратегии, которые работают сейчас не очень, и картина не сильно поменялась в плане прибыли. Зато повысилась стабильность и повысился винрейт.

Если торговать с коэффициентом ослабления критерия Келли 0.2 и процентами выплат 82% у одного брокера и 80% у другого, получается неплохой результат. Винрейт у сигналов разный, но в среднем он 59%. Вот результат теста с начала 2020 года по 26.05.2020. Т.е. этот период вообще никак не участвовал в настройке стратегий. 

Пошел сливать бабосики на бинарках



( Читать дальше )

Блог им. elektroyar |С++ Библиотека для сервера и клиента Named Pipe

В общем, сделал библиотеку simple-named-pipe-server для  работы с именованными каналами. Библиотека содержит сервер и клиент для C++11, а также клиент для MQL4.

С++ Библиотека для сервера и клиента Named Pipe


Очень простая, многопоточная серверная и клиентская библиотека Named Pipe, реализованная с использованием C++11. Проект был проверен на компиляторе mingw 7.3.0 x64. Папка code_blocks содержит примеры для IDE Code::Blocks. Не забудьте в проектах указать свой компилятор, иначе проект не соберется. Сделал либу только сегодня, так что в ней могут быть ошибочки.

Пример сервера
#include <iostream>
#include "named-pipe-server.hpp"

int main() {
    /* в конструкторе сервера можно также задать размер буфера */
    SimpleNamedPipe::NamedPipeServer server("my_server");

    /* обработчики событий */
    server.on_open = [&](SimpleNamedPipe::NamedPipeServer::Connection* connection) {
        std::cout << "open, handle: " << connection->get_handle() << std::endl;
    };
    server.on_message = [&](SimpleNamedPipe::NamedPipeServer::Connection* connection, 
			const std::string &in_message) {
        /* обрабатываем входящие сообщения */
        std::cout << "message " << in_message << ", handle: " << connection->get_handle() << std::endl;
        connection->send("ok");
    };
    server.on_close = [&](SimpleNamedPipe::NamedPipeServer::Connection* connection) {
        std::cout << "close, handle: " << connection->get_handle() << std::endl;
    };
    server.on_error = [&](SimpleNamedPipe::NamedPipeServer::Connection* connection, const std::error_code &ec) {
        std::cout << "error, handle: " << connection->get_handle() << ", what " << ec.value() << std::endl;
    };

    /* запускаем сервер */
    server.start();
    std::system("pause");

    /* останавливаем сервер 
     * (деструктор класса сам выполнит остановку, вызывать не обязательно)
     */
    server.stop();
    std::cout << "close program" << std::endl;
    return EXIT_SUCCESS;
}


( Читать дальше )

Блог им. elektroyar |Супер ускорение расчета индикаторов

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

Например, был ценовой ряд из 6-ти элементов:

1.104, 1.102, 1.105, 1.106, 1.103, 1.101 

Найдем его интегральное представление (начнем с нуля):

0.0, 1.104, 2.206, 3.311, 4.417, 5.52, 6.621

Чему будет равно SMA за последние 3 элемента? Достаточно посчитать разницу: 6.621 - 3.311 и разделить ее на 3.

SMA(3) = (6.621 - 3.311)/3 = 1.103

Убедимся, что SMA(3) найдено верно. 

(1.106 + 1.103 + 1.101)/3 = 1.103

Таким образом можно найти SMA с любым периодом, совершив всего навсего одну операцию вычитания и одну операцию деления. Это позволит гораздо быстрее получить набор значений индикаторов типа SMA, RSI, STD_DEV.
Вроде все хорошо, НО НАДО ПОМНИТЬ, что если использовать тип данных с плавающей точкой, то у нас будет накапливаться ошибка. Поэтому ценовой ряд лучше сначала преобразовать в целочисленный тип. Для этого достаточно для 5-ти значных котировок умножить цену на число 100 000.

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




Блог им. elektroyar |"Мост" между MetaTrader и программой через socket

В жизни бывают такие моменты, когда очень хочется торговать из программы на С++, но по каким-то причинам у брокера нет API, зато есть MetaTrader. Конечно, можно просто писать код на MQL4/MQL5, на этом урезанном варианте-мутанте Си и С++, но мне как-то не в кайф это делать. Поэтому я решил сделать «мост» между MetaTrader и программой через socket. Встречайте — MT-Bridge
"Мост" между MetaTrader и программой через socket

На данный момент MT-Bridge позволяет только передавать поток котировок в программу с заданной частотой + добавлена инициализация исторических данных. Пока мне этого достаточно, но возможно в будущем функционал MT-Bridge будет расширен. Поэтому извиняйте, если здесь вы не нашли полноценного функционала, что есть то есть пока. Библиотека для подключения к советнику написана на С++11 и зависит от boost.asio, но нужны только файлы-заголовки. Вот github репозиторий с советником и библиотекой. Передача данных реализована через сокеты, советник является клинетом, а программа на С++ — сервером. Данные передаются через сокет в бинарном виде. 

( Читать дальше )

Блог им. elektroyar |Бизнес в России VS "лохотроны"

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

Но на практике все не так однозначно, и порой даже в казино шансы отбить деньги могут быть выше, чем отбить деньги вложенные в бизнес.

Потапенко в одном из видео рассказывает: "За 9 месяцев 2019 года зарегистрировано 227 юридических лиц и ликвидировано 529. Убыль — прямая. В обрабатывающей промышленности 15 плюс 33 минус, строительство 42 плюс 74 минус, торговля 75 плюс и 230 минус..."



( Читать дальше )

Блог им. elektroyar |Про программирование в алготрейдинге и полезные навыки

По моему опыту в алготрейдинге (под алготрейдингом я подразумеваю поиск закономерностей и их использование) большая часть времени уходит на исследования, это примерно 90% времени. Однако, часто можно услышать критику примерно следующего плана.
  • Нужно писать код на питоне/джаве, можно в два счета набросать торгового робота. Нафиг Си и С++, сложна.
  • Не нужно изобретать велосипеды, все уже сделано за нас. Зря потратить время, бери готовое и действуй. Метатрейдер в помощь.
  • Нужно всегда писать чистый код, а не говнокод. 
Если все это верно, то получается, что успех в алготрейдинге (да и в IT) должен зависеть от этих факторов. Однако, к примеру, на практике большая часть доли в проекте принадлежит обычно не программистам (т.е. людям, которые вообще могут не уметь программировать), хороший код не обязательно принесет много денег, да и сложные алгоритмы порой без разницы, на каком языке реализовывать, быстрее они не напишутся.

Если объяснить проще, то успех не равен чистоте, хорошести и прочим характеристикам кода. Тогда почему происходит акцентуация на подобные факторы? 

( Читать дальше )

Блог им. elektroyar |Библиотека С++ для загрузки экономических новостей

Есть один хороший сайт www.investing.com с экономическими новостями, которым пользуются многие трейдеры на Форексе. И решил я как-то раз попробовать посмотреть, что будет на бэктестинге торговли по новостям. Поковырявшись в страничке экономического календаря сделал в итоге С++ библиотеку для загрузки новостей. Для http запросов библиотека использует curl. Новости загружаются по UTC времени, загрузить их можно со времен начала эпохи UNIX

Класс для хранения одной новости:
/** \brief Класс Новостей
*/
class News
{
public:
	std::string name;          /**< Имя новости */
	std::string currency;      /**< Валюта новости */
	std::string country;       /**< Страна новости */
	int level_volatility = -1; /**< Уровень волатильности (-1 не инициализировано,  низкий уровень = 0, средний 1, высокий 2) */
	double previous;           /**< Предыдущее значение */
	double actual;             /**< Актуальное значение */
	double forecast;           /**< Предсказанное значение */
	bool is_previous = false;  /**< Наличие предыдущего значения */
	bool is_actual = false;    /**< Наличие актуального значения */
	bool is_forecast = false;  /**< Наличие предсказанного значения */
	uint64_t timestamp = 0;    /**< Метка времени новости */

	News() {};
};
Для хранения массива исторических данных новостей используется библиотека 

( Читать дальше )

Блог им. elektroyar |Хранение статистики индикаторов для ускорения работы оптимизатора и тестирования на истории

Для ускорения тестирования и оптимизации стратегий я обычно заранее вычисляю результат прогноза индикатора для всего диапазона используемых параметров на всей дате тестирования.

В качестве результата прогноза индикатора можно использовать разные варианты. Первый вариант — использовать движение цены за определенное время. Например, для конкретной стратегии используется замер движения цены за три минуты после прогноза. Цена при этом может остаться на том же уровне, что и в начале прогноза, и это надо учитывать. Другой вариант результата прогноза индикатора — исход движения цены при использовании равнозначного фиксированного тейк-профита и стоп-лосса.

Структура хранения данных выглядит так:
Хранение статистики индикаторов для ускорения работы оптимизатора и тестирования на истории

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

( Читать дальше )

....все тэги
UPDONW
Новый дизайн