Паттерн позволяет разделить логику тестирования от логики реального входа внутри робота для того, чтобы при входе и выходе не «рисовать свечи» своими большими заявками.
Очень важная заготовка паттерна управления позицией для тех, у кого много денег на счету. В том числе разберём исходный код, чтобы Вы могли модернизировать свои способы входа в реале, опираясь на данные исходники. В примере логика айсберга выделена в отдельный объект и использована многопоточность, но её надо будет переиспользовать без изменений, поэтому не пугайтесь, кто не программист, переиспользовать удастся. Будете входить, как захотите в реале.
Итоговая логика робота на графике в реале выглядит так:

В примере на графике получилось даже зайти лучше, чем если бы мы это делали одним ордером.
Сам робот – классический отбойник от боллинджера с выходом в % по стопу и профиту. Выход также в реале через «кастомный айсберг».
1. Открываем робот-пример. CustomIcebergSample.
На ГитХаб в репозитории OsEngine это находится здесь:
https://github.com/AlexWan/OsEngine
Внутри проекта здесь:
2. Конструктор и сервисный код.
- Поле для хранения источника BotTabSimple. В это поле потом мы положим объект источника и сможем обращаться к нему из любой части робота. Так удобнее.
- Поле для хранения индикатора.
- Параметры. Чуть позже поговорим про каждый.
- Создание источника BotTabSimple.
- Создание параметров.
- Создание индикатора Bollinger. Установка его длины и отклонения из параметров.
- Подписка на событие CandleFinishedEvent (завершение свечи). В обработчике этого события будет вся торговая логика.
- Подписка на событие изменение параметров. В этом обработчике мы будем устанавливать индикатору новое значение длины.
- Отключаем автоматическое сопровождение позиции.
Настройки такие:
За что отвечают параметры:
1.Regime – режим работы.- Off – Выключен.
- On – Включен и будет входить и в лонг и в шорт.
- OnlyLong – открытие только длинных позиций.
- OnlyShort – открытие только коротких позиций.
- OnlyClosePosition – доступно только закрытие позиций.
2. Volume type – режим выбора объёма.- Contracts – кол-во контрактов инструмента.
- Contract currency – валюта контракта.
- Deposit percent – процент от депозита.
3. Volume – значение объёма. Что именно, зависит от предыдущего пункта. В случае Contracts тут указывается объём инструмента. В случае Contract currency здесь указывается кол-во рублей или долларов, которыми нужно войти. В случае с Deposit percent здесь указывается % от общего депозита, которым нужно войти в контракт.
4. Asset in portfolio – тут нужно указывать название валюты, которое будет использовано для расчёта объёма, если Вы выбрали тип объёма “Deposit percent”. В тестере оставляем «Prime». На крипте это обычно “USDT”.
5. Bollinger length – длина индикатора Bollinger.
6. Bollinger deviation – отклонение для индикатора Bollinger.
7. Profit percent – движение от входа до выхода в %. Для установки профит-приказа.
8. Stop percent – движение от входа до выхода в %. Для установки стоп-приказа.
9. Iceberg count – количество ордеров, которым будет взят установленный объём.
10. Iceberg seconds between orders – время между ордерами в секундах.
3. Вход в логику в событии завершения свечи.

- Если режим робота Off, выходим из метода.
- Если данных по индикатору нет, выходим из метода.
- Если данных в индикаторе меньше, чем его длина расчёта, выходим из метода.
- Берём все позиции у источника.
- Если позиций нет, но режим не позволяет открывать новые позиции, выходим из метода.
- Если позиций нет и режим позволяет, идём в метод открытия позиции.
- Если позиции есть, идём в метод закрытия позиций.
4. Логика открытия позиций.
- Берём значения Bollinger и цену закрытия последней свечи.
- Если вдруг значения индикатора равны нулю, выходим из метода.
- Если цена выше верхней линии боллинджера, это сигнал зайти в шорт.
- Если мы в тестере или оптимизаторе, то заходим по маркету всем объёмом.
- Если мы в реальных торгах, создаём объект «IcebergMaker» для входа в шорт по заданному кол-ву ордеров.
- Если цена ниже нижней линии боллинджера, это сигнал зайти в лонг.
- Если мы в тестере или оптимизаторе, заходим по маркету всем объёмом.
- Если мы в реальных торгах, создаём объект «IcebergMaker» для входа в шорт по заданному кол-ву ордеров.
5. Логика закрытия позиций.

- Если статус позиции не Open, выходим из метода. Либо позиция ещё открывается, либо уже закрывается.
- Берём цену закрытия последней свечи с рынка.
- Расчёт и проверка профита для ЛОНГ позиции.
- Обратите внимание, что для того, чтобы не дублировать код, создание айсберга на закрытие вынесено в отдельный метод. ClosePos.
- Расчёт и проверка профита для ШОРТ позиции.
- Расчёт и проверка стопа для ЛОНГ позиции.
- Расчёт и проверка стопа для ШОРТ позиции.
- Если мы в тестере или оптимизаторе, закрываемся по маркету всем объёмом.
- Если мы в реале, создаём объект для закрытия позиции.
6. Создание Iceberg для открытия позиции.

- Создание объекта «icebergMaker».
- Указываем объём, которым нужно будет открыться.
- Указываем кол-во ордеров, которыми будет открыт этот объём.
- Указываем кол-во секунд между ордерами.
- Указываем источник, по которому будет открыта позиция.
- Указываем сторону, в которую надо открывать позицию. Side.Buy / Side.Sell
- Вызываем метод Start(). Он запускает процесс набора позиции.
7. Создание Iceberg на закрытие позиции.

- Создание объекта «icebergMaker».
- Указываем кол-во ордеров, которыми будет закрыта позиция.
- Указываем кол-во секунд между ордерами.
- Указываем источник, по которому будет закрыта позиция.
- Указываем позицию, которую нужно закрыть.
- Вызываем метод Start(). Он запускает процесс закрытия позиции.
8. IcebergMaker. Сервис.

- Кол-во ордеров, которыми будет открыт этот объём.
- Кол-во секунд между ордерами.
- Объём для открытия позиции.
- Источник, по которому нужно открывать или закрывать позицию.
- Сторона открытия позиции, если её надо открывать.
- Позиция для закрытия.
- Позиция открывающаяся. Её указывать не нужно. Это сервисное поле, в которое сохраняется позиция во время открытия.
- Вызываем метод Start(). Он запускает процесс набора или закрытия позиции.
- Если позиция для закрытия не указана, значит надо открывать позицию. Вызываем метод OpenPositionMethod.
- Если позиция для закрытия указана, значит надо закрывать позицию. Вызываем метод ClosePositionMethod.
9. IcebergMaker. Логика открытия позиции.
- Если кол-во ордеров указано меньше 1, то ставим минимум 1 ордер.
- Рассчитываем все объёмы для ордеров, которыми будем входить.
- В случае, если расчётный объём не совпадает с указанным пользователем из-за «округлений», в первый ордер добавляем потерянный объём.
- Цикл открытия позиции.
- Buy. Если зашли в цикл впервые, вызываем метод BuyAtMarket, создавая новую позицию.
- Buy. Если зашли в цикл не в первый раз, докупаем для ранее созданной позиции, вызывая метод BuyAtMarketToPosition.
- Sell. Если зашли в цикл впервые, вызываем метод SellAtMarket, создавая новую позицию.
- Sell. Если зашли в цикл не в первый раз, допродаём для ранее созданной позиции, вызывая метод SellAtMarketToPosition.
10. IcebergMaker. Логика закрытия позиции.

- Если кол-во ордеров указано меньше 1, то ставим минимум 1 ордер.
- Берём из позиции текущий объём, его и будем закрывать.
- Считаем для каждого будущего ордера объём заранее.
- В случае, если расчётный объём не совпадает с указанным пользователем из-за «округлений», в первый ордер добавляем потерянный объём.
- Цикл для выставления ордеров на закрытие позиций.
11. На выходе.
Робот, торгующий классическую контртрендовую стратегию по каналу Bollinger, но в реале входящий и выходящий серией заявок, а не одной:

Удачных алгоритмов!
Комментарии открыты для друзей!

OsEngine: https://github.com/AlexWan/OsEngine
Поддержка OsEngine: https://t.me/osengine_official_support
Регистрируйся в АЛОР и получай бонусы: https://www.alorbroker.ru/open
Сайт АЛОР БРОКЕР: https://www.alorbroker.ru
Раздел «Для клиентов»: https://www.alorbroker.ru/openinfo/for-clients
Программа лояльности от АЛОР БРОКЕР и OsEngine: https://smart-lab.ru/company/os_engine/blog/972745.php
