Дублирование заявок при тестировании робота, работающего по лимитным ордерам

При тестировании робота в OS.Tester, который работает лимитными ордерами, возможно дублирование заявок

  1. Сергей Борисов

    Регистрация:
    23.02.17
    Сообщения:
    42
    Был на сайте:
    09.02.18

    Файл \OsEngine\OsTrader\Panels\Tab\BotTabSimple.cs - стр. 2883 - метод CheckStopOpener(decimal price)

    В цикле перебираются заявки, ожидающие своей цены для открытия. Внутри цикла используются методы LongCreate() и ShortCreate(), в результате работы которых исполненные заявки удаляются из коллекции, которая перебирается в цикле. Это приводит либо к критической ошибке при удалении заявки строке:

    _stopsOpener.Remove(_stopsOpener[i]) (нет значения по индексу),

    либо к дублированию выполнения заявок (там все сложнее, можно проверить на тестовых данных.

    Вариант решения:

    1. Открываем все, что пора открывать
    2. Если что-то открылось, то остальное удаляем из очереди ожидания

    Код:

    private void CheckStopOpener(decimal price)
    {
    try
    {
    // 1. Создаем копию пула заявок
    List copyOf_stopsOpener = new List(_stopsOpener);
    // 2. Открываем все, что пора открывать
    bool itWasNewDeal = false;
    foreach (var stopOrder in copyOf_stopsOpener)
    {
    if ((stopOrder.ActivateType == StopActivateType.HigherOrEqual &&
    price >= stopOrder.PriceRedLine) // пробили вниз
    ||
    (stopOrder.ActivateType == StopActivateType.LowerOrEqyal &&
    price <= stopOrder.PriceRedLine)) // пробили вверх
    {
    if (stopOrder.Side == Side.Buy)
    {
    Position newDeal = LongCreate(stopOrder.PriceOrder, stopOrder.Volume, OrderPriceType.Limit, _manualControl.SecondToOpen, true);
    if (newDeal != null)
    {
    itWasNewDeal = true;
    }
    }
    else if (stopOrder.Side == Side.Sell)
    {
    Position newDeal = ShortCreate(stopOrder.PriceOrder, stopOrder.Volume, OrderPriceType.Limit, _manualControl.SecondToOpen, true);
    if (newDeal != null)
    {
    itWasNewDeal = true;
    }
    }
    }
    }
    // 3. Если что-то открылось, то остальное удаляем из очереди ожидания
    if (itWasNewDeal)
    {
    _stopsOpener.Clear();
    }
    }
    catch (Exception error)
    {
    SetNewLogMessage(error.ToString(), LogMessageType.Error);
    }
    }

    Сергей Борисов
    02.04.2017 20:47
    #1
  2. Алексей Ван Команда форума

    Регистрация:
    02.02.13
    Сообщения:
    1172
    Был на сайте:
    25.04.24

    поменял _stopsOpener.Remove(_stopsOpener[i]) на _stopsOpener.RemoveAt(i);

    должно корректно удаление отрабатываться. В этом проблема.

    Алексей Ван
    09.04.2017 18:54
    #2