Отличная статья!
Какие пары вы рекомендуете для этого Algo?
Какие таймфреймы? М5, М30 и т.д.
Какая сессия?
Спасибо и наилучшие пожелания
Тестировал ваш алгоритм.
В файле ExecutionAlgorithm.mqh добавил эту строку request.type_filling = ORDER_FILLING_IOC; при выставлении ордера, чтобы исправить проблему с выставлением ордера.
Протестировал на M5, открыта только 1 сделка за 2 месяца, частичных ордеров не открывалось.
Протестировал на H1, не применил ни SL, ни TP, все сделки закрылись в убыток.
также при компиляции выдает предупреждения
подскажите, как протестировать algo,
временные рамки. и любые другие рекомендации.
также при компиляции выдает предупреждения
я изменил строку кода
m_volumeProfile[intervalIndex] += rates[i].tick_volu
на
Это устранило предупреждения
Теперь нужна ваша помощь в отношении других моих запросов, как
Таймфрейм
А также
почему все сделки во время бэктеста приводят к убыткам
как проверить эту большую работу от вас.
подскажите, как протестировать algo,
временные рамки. и любые другие рекомендации.
Предупреждения не являются проблемой, но их можно быстро исправить. Но да, было бы здорово, если бы автор пошагово показал, какие настройки и входы он использовал для бэктеста.
Я согласен с Домиником, поскольку предупреждения - это всего лишь предупреждения. Результаты I_Virgo, вероятно, связаны с тем, что он использовал неправильный таймфрейм и валютную пару. Судя по отчету Back Test из почти 2000 баров, это должен был быть либо M1, либо M5 в качестве таймфрейма с неизвестной парой.
Было бы неплохо, если бы MQ добавил в отчет Back Test таймфрейм и валютную пару или пары, а также более подробно разделил результаты по парам, чтобы мы могли более точно воспроизвести результаты обратного тестирования автора, а также определить его применимость к парам Форекс. Также было бы очень полезно, если бы советник мог выводить текст на график во время работы.
Я также считаю, что это отличная статья, и планирую тщательно изучить ее в ожидании адаптации его методов к другим советникам
CapeCoddah
//+------------------------------------------------------------------+ //| Базовый класс для всех алгоритмов выполнения| //+------------------------------------------------------------------+ class CExecutionAlgorithm { protected: string m_symbol; // Торговый символ double m_totalVolume; // Общий объем для выполнения double m_executedVolume; // Объем уже выполнен double m_remainingVolume; // Оставшийся объем для выполнения datetime m_startTime; // Время начала выполнения datetime m_endTime; // Время окончания выполнения int m_slippage; // Допущенное отставание в очках bool m_isActive; // Активен ли алгоритм в данный момент // Статистика double m_avgExecutionPrice; // Средняя цена исполнения int m_totalOrders; // Общее количество размещенных заказов int m_filledOrders; // Количество выполненных заказов public: // Конструктор CExecutionAlgorithm(string symbol, double volume, datetime startTime, datetime endTime, int slippage); // Деструктор virtual ~CExecutionAlgorithm(); // Виртуальные методы, которые должны быть реализованы производными классами virtual bool Initialize(); virtual bool Execute() = 0; virtual bool Update() = 0; virtual bool Terminate() = 0; // Общие методы bool IsActive() { return m_isActive; } double GetExecutedVolume() { return m_executedVolume; } double GetRemainingVolume() { return m_remainingVolume; } double GetAverageExecutionPrice() { return m_avgExecutionPrice; } // Вспомогательные методы bool PlaceOrder(ENUM_ORDER_TYPE orderType, double volume, double price = 0.0); bool ModifyOrder(ulong ticket, double price, double sl, double tp); bool CancelOrder(ulong ticket); void UpdateAverageExecutionPrice(double price, double volume); // Метод-помощник для получения соответствующего режима заполнения ENUM_ORDER_TYPE_FILLING GetFillingMode(); }; //+------------------------------------------------------------------+ //| Конструктор| //+------------------------------------------------------------------+ CExecutionAlgorithm::CExecutionAlgorithm(string symbol, double volume, datetime startTime, datetime endTime, int slippage) { m_symbol = symbol; m_totalVolume = volume; m_executedVolume = 0.0; m_remainingVolume = volume; m_startTime = startTime; m_endTime = endTime; m_slippage = slippage; m_isActive = false; m_avgExecutionPrice = 0.0; m_totalOrders = 0; m_filledOrders = 0; } //+------------------------------------------------------------------+ //| Деструктор| //+------------------------------------------------------------------+ CExecutionAlgorithm::~CExecutionAlgorithm() { // Очистите ресурсы, если это необходимо } //+------------------------------------------------------------------+ //| Инициализация алгоритма| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::Initialize() { // Проверка вводимых данных if(m_symbol == "" || m_totalVolume <= 0.0) { Print("Invalid inputs for execution algorithm"); return false; } // Проверьте, существует ли символ if(!SymbolSelect(m_symbol, true)) { Print("Symbol not found: ", m_symbol); return false; } // Сброс статистики m_executedVolume = 0.0; m_remainingVolume = m_totalVolume; m_avgExecutionPrice = 0.0; m_totalOrders = 0; m_filledOrders = 0; return true; } //+------------------------------------------------------------------+ //| Получите соответствующий режим заполнения для символа | //+------------------------------------------------------------------+ ENUM_ORDER_TYPE_FILLING CExecutionAlgorithm::GetFillingMode() { // Получение режимов заполнения символов int filling_modes = (int)SymbolInfoInteger(m_symbol, SYMBOL_FILLING_MODE); // Проверьте доступные режимы заполнения в порядке предпочтения if((filling_modes & SYMBOL_FILLING_FOK) == SYMBOL_FILLING_FOK) return ORDER_FILLING_FOK; else if((filling_modes & SYMBOL_FILLING_IOC) == SYMBOL_FILLING_IOC) return ORDER_FILLING_IOC; else return ORDER_FILLING_RETURN; } //+------------------------------------------------------------------+ //| Разместить заказ| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::PlaceOrder(ENUM_ORDER_TYPE orderType, double volume, double price = 0.0) { // Проверка вводимых данных if(volume <= 0.0) { Print("Invalid order volume"); return false; } // Подготовьте запрос MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.symbol = m_symbol; request.volume = volume; request.type = orderType; request.deviation = m_slippage; request.magic = 123456; // Магическое число для идентификации // Установите соответствующее действие и цену в зависимости от типа ордера if(orderType == ORDER_TYPE_BUY || orderType == ORDER_TYPE_SELL) { // Рыночный ордер request.action = TRADE_ACTION_DEAL; request.type_filling = GetFillingMode(); if(orderType == ORDER_TYPE_BUY) request.price = SymbolInfoDouble(m_symbol, SYMBOL_ASK); else request.price = SymbolInfoDouble(m_symbol, SYMBOL_BID); } else { // Отложенный ордер request.action = TRADE_ACTION_PENDING; if(price <= 0.0) { Print("Price must be specified for pending orders"); return false; } request.price = price; } // Отправить заказ if(!OrderSend(request, result)) { Print("OrderSend error: ", GetLastError()); return false; } // Проверьте результат if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderSend failed with code: ", result.retcode, " - ", result.comment); return false; } // Обновление статистики m_totalOrders++; // Для рыночных ордеров обновлять статистику выполнения немедленно if(orderType == ORDER_TYPE_BUY || orderType == ORDER_TYPE_SELL) { m_filledOrders++; UpdateAverageExecutionPrice(request.price, volume); m_executedVolume += volume; m_remainingVolume -= volume; } Print("Order placed successfully. Ticket: ", result.order, " Volume: ", volume, " Price: ", request.price); return true; } //+------------------------------------------------------------------+ //| Изменить существующий заказ| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::ModifyOrder(ulong ticket, double price, double sl, double tp) { // Подготовьте запрос MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.action = TRADE_ACTION_MODIFY; request.order = ticket; request.price = price; request.sl = sl; request.tp = tp; // Отправьте запрос на модификацию if(!OrderSend(request, result)) { Print("OrderModify error: ", GetLastError()); return false; } // Проверьте результат if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderModify failed with code: ", result.retcode, " - ", result.comment); return false; } Print("Order modified successfully. Ticket: ", ticket); return true; } //+------------------------------------------------------------------+ //| Отменить существующий заказ| //+------------------------------------------------------------------+ bool CExecutionAlgorithm::CancelOrder(ulong ticket) { // Подготовьте запрос MqlTradeRequest request; MqlTradeResult result; ZeroMemory(request); request.action = TRADE_ACTION_REMOVE; request.order = ticket; // Отправьте запрос на отмену if(!OrderSend(request, result)) { Print("OrderCancel error: ", GetLastError()); return false; } // Проверьте результат if(result.retcode != TRADE_RETCODE_DONE) { Print("OrderCancel failed with code: ", result.retcode, " - ", result.comment); return false; } Print("Order cancelled successfully. Ticket: ", ticket); return true; } //+------------------------------------------------------------------+ //| Обновление средней цены выполнения| //+------------------------------------------------------------------+ void CExecutionAlgorithm::UpdateAverageExecutionPrice(double price, double volume) { // Рассчитываем новую среднюю цену исполнения if(m_executedVolume > 0.0) { // Средневзвешенное значение старой и новой цен m_avgExecutionPrice = (m_avgExecutionPrice * m_executedVolume + price * volume) / (m_executedVolume + volume); } else { // Первое выполнение m_avgExecutionPrice = price; } } //+------------------------------------------------------------------+
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Опубликована статья Передовые алгоритмы исполнения ордеров на MQL5: TWAP, VWAP и ордера Iceberg:
«Конечно», — можете вы пожать плечами, — «но я не перемещаю институциональные суммы». Вот в чем загвоздка: вам это делать не обязательно. Независимо от того, используете ли вы половину лота или несколько мини-лотов, волатильность все равно может исказить ваше исполнение. Эти инструменты помогут вам:
Оставайтесь незамеченными: В частности, ордера Iceberg скрывают истинный размер вашего ордера, заставляя любопытные алгоритмы гадать.
Сегодняшняя демократизированная среда означает, что те же технологии исполнения, которые когда-то требовали многомиллионных бюджетов, теперь могут работать на вашей персональной торговой станции. Добавив в свою платформу отточенный код на MQL5 для стратегий TWAP, VWAP и Iceberg, вы вооружитесь институциональной огневой мощью, не покидая при этом сферу розничной торговли.
Автор: N Soumik