Расчет лота для фьючерсов MOEX в MQL5 с учетом шага цены

Расчет лота для фьючерсов MOEX в MQL5 с учетом шага цены MQL4 / MQL5 (MetaTrader)
Профессиональное руководство по расчету объема лота для фьючерсов Московской Биржи (MOEX) в MQL5. Готовый код с учетом шага цены и стоимости тика.
Суть: Для корректного расчета лота на срочном рынке MOEX (FORTS) в MQL5 необходимо использовать формулу стоимости пункта: PointValue = SYMBOL_TRADE_TICK_VALUE / SYMBOL_TRADE_TICK_SIZE. Итоговый объем рассчитывается как отношение допустимого риска к произведению стоп-лосса на стоимость пункта, с последующим округлением до SYMBOL_VOLUME_STEP.

Исходный код

В отличие от классического валютного рынка Forex, где расчет лота часто привязан к свободной марже (подробнее об этом читайте в статье Расчет лота от свободной маржи в MQL4: Скрипт с автоокруглением), на срочном рынке Московской Биржи (MOEX) мы сталкиваемся с уникальной спецификой: цена шага и сам шаг цены могут динамически меняться, а гарантийное обеспечение (ГО) не эквивалентно стандартному кредитному плечу.

Перед тем как рассчитать объем входа, профессиональные трейдеры оценивают текущее состояние рынка. Рекомендуем использовать Скрипт определения фазы рынка (Флэт/Тренд) на MQL5: ADX + Bollinger Bands, чтобы адаптировать размер стоп-лосса под текущую волатильность рынка перед вызовом функции расчета лота.

Ниже представлен готовый к интеграции класс-хелпер на MQL5, который безошибочно рассчитывает объем позиции для фьючерсов Московской Биржи:

//+------------------------------------------------------------------+
//|                                            MOEXLotCalculator.mqh |
//|                                      Copyright 2024, Finfluct    |
//|                                            https://finfluct.com  |
//+------------------------------------------------------------------+
#property library
#property strict

class CMOEXLotCalculator
{
public:
    // Метод расчета лота по риску в валюте депозита
    static double CalculateLot(const string symbol, const double riskAmount, const double stopLossPoints)
    {
        if(stopLossPoints <= 0.0 || riskAmount <= 0.0)
        {
            Print("MOEXLotCalculator: Некорректные входные параметры. SL или Риск <= 0");
            return 0.0;
        }

        // Получаем шаг цены фьючерса (например, 1 или 10)
        double tickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
        // Получаем стоимость шага цены в валюте депозита
        double tickValue = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE);

        if(tickSize <= 0.0 || tickValue <= 0.0)
        {
            Print("MOEXLotCalculator: Ошибка получения спецификации символа ", symbol);
            return 0.0;
        }

        // На MOEX стоимость одного пункта изменения цены равна: TickValue / TickSize
        double pointValue = tickValue / tickSize;

        // Рассчитываем риск на 1 контракт в валюте депозита при заданном стоп-лоссе
        double riskPerContract = stopLossPoints * pointValue;
        if(riskPerContract <= 0.0)
        {
            Print("MOEXLotCalculator: Ошибка расчета риска на контракт.");
            return 0.0;
        }

        // Предварительный объем лота
        double rawLot = riskAmount / riskPerContract;

        // Округление лота согласно спецификации контракта
        double volumeStep = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
        double minVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
        double maxVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);

        if(volumeStep <= 0.0) volumeStep = 1.0;

        // Округляем строго вниз для соблюдения риск-менеджмента
        double calculatedLot = MathFloor(rawLot / volumeStep) * volumeStep;

        // Проверка на выход за границы лимитов брокера/биржи
        if(calculatedLot < minVolume)
        {
            // Проверяем, укладывается ли минимальный лот в наш риск-лимит
            if(minVolume * riskPerContract <= riskAmount)
            {
                calculatedLot = minVolume;
            }
            else
            {
                calculatedLot = 0.0; // Риск превышен даже при минимальном лоте
            }
        }

        if(calculatedLot > maxVolume)
        {
            calculatedLot = maxVolume;
        }

        return calculatedLot;
    }
};

Разбор параметров

  • symbol: Торговый инструмент (тикер фьючерса на MOEX, например, RTS-12.24 или Si-12.24).
  • riskAmount: Максимально допустимый убыток на сделку в валюте депозита (обычно в рублях).
  • stopLossPoints: Размер стоп-лосса в пунктах торгового инструмента (разница между ценой входа и ценой стоп-лосса).
  • SYMBOL_TRADE_TICK_SIZE: Минимальный шаг изменения цены фьючерса. На MOEX он может быть равен 1, 10 или дробным значениям.
  • SYMBOL_TRADE_TICK_VALUE: Стоимость минимального шага цены в валюте депозита. Динамический параметр, который транслируется биржей.
  • SYMBOL_VOLUME_STEP: Минимальный шаг изменения объема контракта. Для фьючерсов MOEX он практически всегда равен 1.0.

Как запустить

Для интеграции этого решения в вашего торгового робота выполните следующие шаги:

1. Создайте новый включаемый файл (класс) с именем MOEXLotCalculator.mqh в папке MQL5/Include/ вашего терминала MetaTrader 5 и скопируйте туда представленный выше код.

2. Подключите созданный файл в вашем советнике с помощью директивы #include .

3. Вызовите статический метод CMOEXLotCalculator::CalculateLot(_Symbol, RiskInRubles, StopLossInPoints) перед отправкой торгового приказа.

Этот подход критически важен при построении сложных алгоритмов исполнения, таких как Реализация сессиного VWAP в MQL5: Пошаговое руководство, где точность входа и соблюдение риск-параметров определяют итоговый математический результат торговой системы.

Оцените статью
FinFluct