Стандартный вход на свечках. Трейлинг стоп по ленте сделок. Микроменеджмент позиций в OsEngine#10

Сегодня будем смотреть пример, в котором трейлинг стоп по позиции подтягивается по ленте сделок, а сама позиция открывается из события завершения свечи.На графике это выглядит так:  1. Открываем робот-пример. StopByTradeFeedSample.На гитХаб исходник примера находится здесь:https://github.com/AlexWan/OsEngine/blob/master/project/OsEngine/Robots/TechSamples/StopByTradeFeedSample.csВнутри проекта: 2. Конструктор и сервисный код.КОДprivate BotTabSimple _tab; private Aindicator _pc; public StrategyParameterString Regime; public StrategyParameterInt IndLength; public StrategyParameterDecimal TrailStopPercent; public StrategyParameterInt Slippage; public StrategyParameterString VolumeType; public StrategyParameterDecimal Volume; public StrategyParameterString TradeAssetInPortfolio; public StopByTradeFeedSample(string name, StartProgram startProgram) : base(name, startProgram) { TabCreate(BotTabType.Simple); _tab = TabsSimple[0]; Regime = CreateParameter("Regime", "Off", new[] { "Off", "On", "OnlyLong", "OnlyShort", "OnlyClosePosition" }); Slippage = CreateParameter("Slippage in price step", 0, 0, 20, 1); IndLength = CreateParameter("Price channel length", 10, 10, 80, 3); TrailStopPercent = CreateParameter("Trail stop percent", 0.2m, 0.5m, 5, 4); VolumeType = CreateParameter("Volume type", "Deposit percent", new[] { "Contracts", "Contract currency", "Deposit percent" }); Volume = CreateParameter("Volume", 10, 1.0m, 50, 4); TradeAssetInPortfolio = CreateParameter("Asset in portfolio", "Prime"); _pc = IndicatorsFactory.CreateIndicatorByName("PriceChannel", name + "PriceChannel", false); _pc = (Aindicator)_tab.CreateCandleIndicator(_pc, "Prime"); _pc.ParametersDigit[0].Value = IndLength.ValueInt; _pc.ParametersDigit[1].Value = IndLength.ValueInt; _pc.Save(); _tab.CandleFinishedEvent += _tab_CandleFinishedEvent; _tab.NewTickEvent += _tab_NewTickEvent; ParametrsChangeByUser += Event_ParametrsChangeByUser; Description = "An example of a robot that pulls up the stop for a position based on changes in the deals feed. IMPORTANT! Tests of this robot should be conducted on the deals feed."; }КОНЕЦ КОДАВ картинке:Поле для хранения источника BotTabSimple. В это поле потом мы положим объект источника и сможем обращаться к нему из любой части робота. Так удобнее.Поле для хранения индикатора.Параметры. Чуть позже поговорим про каждый.Создание источника BotTabSimple.Создание параметров.Создание индикатора PriceChannel. Установка его длины и отклонения из параметров.Подписка на событие CandleFinishedEvent (завершение свечи). В обработчике этого события логика открытия позиции.Подписка на событие NewTickEvent (новый трейд в ленте сделок). В обработчике этого события будет подтягивание стопа.Подписка на событие изменение параметров. В этом обработчике мы будем устанавливать индикатору новое значение длины. 3. Настройки и параметры.Создание параметров происходит в конструкторе робота:КОДRegime = CreateParameter("Regime", "Off", new[] { "Off", "On", "OnlyLong", "OnlyShort", "OnlyClosePosition" }); Slippage = CreateParameter("Slippage in price step", 0, 0, 20, 1); IndLength = CreateParameter("Price channel length", 10, 10, 80, 3); TrailStopPercent = CreateParameter("Trail stop percent", 0.2m, 0.5m, 5, 4); VolumeType = CreateParameter("Volume type", "Deposit percent", new[] { "Contracts", "Contract currency", "Deposit percent" }); Volume = CreateParameter("Volume", 10, 1.0m, 50, 4); TradeAssetInPortfolio = CreateParameter("Asset in portfolio", "Prime");КОНЕЦ КОДАВ окне параметров это выглядит так:За что отвечают параметры:Regime – режим работы.Off – Выключен.On – включено без ограничений.OnlyLong – открытие только длинных позиций.OnlyShort – открытие только коротких позиций.OnlyClosePosition – доступно только закрытие позиций.Slippage in price step – проскальзывание для открытия и закрытия позиций в шагах цены.Price channel length – длина индикатора PriceChannel.Trail stop percent – величина трейлинг стопа для позиций в процентах.Volume type – режим выбора объёма.Contracts – кол-во контрактов инструмента.Contract currency – валюта контракта.Deposit percent – процент от депозита.Volume – значение объёма. Что именно, зависит от предыдущего пункта. В случае Contracts тут указывается объём инструмента. В случае Contract currency здесь указывается кол-во рублей или долларов, которыми нужно войти. В случае с Deposit percent здесь указывается % от общего депозита, которым нужно войти в контракт.Asset in portfolio – тут нужно указывать название валюты, которое будет использовано для расчёта объёма

Апр 14, 2025 - 18:51
 0
Стандартный вход на свечках. Трейлинг стоп по ленте сделок. Микроменеджмент позиций в OsEngine#10

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

На графике это выглядит так:

Стандартный вход на свечках. Трейлинг стоп по ленте сделок. Микроменеджмент позиций в OsEngine#10 

 

1. Открываем робот-пример. StopByTradeFeedSample.

На гитХаб исходник примера находится здесь:

https://github.com/AlexWan/OsEngine/blob/master/project/OsEngine/Robots/TechSamples/StopByTradeFeedSample.cs

Внутри проекта:

Стандартный вход на свечках. Трейлинг стоп по ленте сделок. Микроменеджмент позиций в OsEngine#10

2. Конструктор и сервисный код.

КОД

private BotTabSimple _tab;

        private Aindicator _pc;

        public StrategyParameterString Regime;

        public StrategyParameterInt IndLength;

        public StrategyParameterDecimal TrailStopPercent;

        public StrategyParameterInt Slippage;

        public StrategyParameterString VolumeType;

        public StrategyParameterDecimal Volume;

        public StrategyParameterString TradeAssetInPortfolio;

        public StopByTradeFeedSample(string name, StartProgram startProgram)
      : base(name, startProgram)
        {
            TabCreate(BotTabType.Simple);
            _tab = TabsSimple[0];

            Regime = CreateParameter("Regime", "Off", new[] { "Off", "On", "OnlyLong", "OnlyShort", "OnlyClosePosition" });
            Slippage = CreateParameter("Slippage in price step", 0, 0, 20, 1);
            IndLength = CreateParameter("Price channel length", 10, 10, 80, 3);

            TrailStopPercent = CreateParameter("Trail stop percent", 0.2m, 0.5m, 5, 4);

            VolumeType = CreateParameter("Volume type", "Deposit percent", new[] { "Contracts", "Contract currency", "Deposit percent" });
            Volume = CreateParameter("Volume", 10, 1.0m, 50, 4);
            TradeAssetInPortfolio = CreateParameter("Asset in portfolio", "Prime");

            _pc = IndicatorsFactory.CreateIndicatorByName("PriceChannel", name + "PriceChannel", false);
            _pc = (Aindicator)_tab.CreateCandleIndicator(_pc, "Prime");
            _pc.ParametersDigit[0].Value = IndLength.ValueInt;
            _pc.ParametersDigit[1].Value = IndLength.ValueInt;
            _pc.Save();

            _tab.CandleFinishedEvent += _tab_CandleFinishedEvent;

            _tab.NewTickEvent += _tab_NewTickEvent;

            ParametrsChangeByUser += Event_ParametrsChangeByUser;

            Description = "An example of a robot that pulls up the stop for a position based on changes in the deals feed. IMPORTANT! Tests of this robot should be conducted on the deals feed.";
        }

КОНЕЦ КОДА

В картинке:

Стандартный вход на свечках. Трейлинг стоп по ленте сделок. Микроменеджмент позиций в OsEngine#10

  1. Поле для хранения источника BotTabSimple. В это поле потом мы положим объект источника и сможем обращаться к нему из любой части робота. Так удобнее.
  2. Поле для хранения индикатора.
  3. Параметры. Чуть позже поговорим про каждый.
  4. Создание источника BotTabSimple.
  5. Создание параметров.
  6. Создание индикатора PriceChannel. Установка его длины и отклонения из параметров.
  7. Подписка на событие CandleFinishedEvent (завершение свечи). В обработчике этого события логика открытия позиции.
  8. Подписка на событие NewTickEvent (новый трейд в ленте сделок). В обработчике этого события будет подтягивание стопа.
  9. Подписка на событие изменение параметров. В этом обработчике мы будем устанавливать индикатору новое значение длины.

 

3. Настройки и параметры.

Создание параметров происходит в конструкторе робота:

КОД

Regime = CreateParameter("Regime", "Off", new[] { "Off", "On", "OnlyLong", "OnlyShort", "OnlyClosePosition" });
            Slippage = CreateParameter("Slippage in price step", 0, 0, 20, 1);
            IndLength = CreateParameter("Price channel length", 10, 10, 80, 3);

            TrailStopPercent = CreateParameter("Trail stop percent", 0.2m, 0.5m, 5, 4);

            VolumeType = CreateParameter("Volume type", "Deposit percent", new[] { "Contracts", "Contract currency", "Deposit percent" });
            Volume = CreateParameter("Volume", 10, 1.0m, 50, 4);
            TradeAssetInPortfolio = CreateParameter("Asset in portfolio", "Prime");

КОНЕЦ КОДА

В окне параметров это выглядит так:

Стандартный вход на свечках. Трейлинг стоп по ленте сделок. Микроменеджмент позиций в OsEngine#10

За что отвечают параметры:

  1. Regime – режим работы.
    1. Off – Выключен.
    2. On – включено без ограничений.
    3. OnlyLong – открытие только длинных позиций.
    4. OnlyShort – открытие только коротких позиций.
    5. OnlyClosePosition – доступно только закрытие позиций.
  2. Slippage in price step – проскальзывание для открытия и закрытия позиций в шагах цены.
  3. Price channel length – длина индикатора PriceChannel.
  4. Trail stop percent – величина трейлинг стопа для позиций в процентах.
  5. Volume type – режим выбора объёма.
    1. Contracts – кол-во контрактов инструмента.
    2. Contract currency – валюта контракта.
    3. Deposit percent – процент от депозита.
  6. Volume – значение объёма. Что именно, зависит от предыдущего пункта. В случае Contracts тут указывается объём инструмента. В случае Contract currency здесь указывается кол-во рублей или долларов, которыми нужно войти. В случае с Deposit percent здесь указывается % от общего депозита, которым нужно войти в контракт.
  7. Asset in portfolio – тут нужно указывать название валюты, которое будет использовано для расчёта объёма, если Вы выбрали тип объёма “Deposit percent”. В тестере оставляем «Prime». На крипте это обычно “USDT”.

 

4. Вход в логику в событии завершения свечи. Открытие позиции.

КОД

private void _tab_CandleFinishedEvent(List candles)
        {
            if (Regime.ValueString == "Off")
            {
                return;
            }

            if (_pc.DataSeries[0].Values == null 
                || _pc.DataSeries[1].Values == null)
            {
                return;
            }

            if (_pc.DataSeries[0].Values.Count < _pc.ParametersDigit[0].Value + 2 
                || _pc.DataSeries[1].Values.Count < _pc.ParametersDigit[1].Value + 2)
            {
                return;
            }

            if (Regime.ValueString == "OnlyClosePosition")
            {
                return;
            }

            List openPositions = _tab.PositionsOpenAll;

            if (openPositions == null
                || openPositions.Count == 0)
            {// no positions
                decimal lastPrice = candles[candles.Count - 1].Close;
                decimal lastPcUp = _pc.DataSeries[0].Values[_pc.DataSeries[0].Values.Count - 2];
                decimal lastPcDown = _pc.DataSeries[1].Values[_pc.DataSeries[1].Values.Count - 2];

                // long
                if (Regime.ValueString != "OnlyShort")
                {
                    if (lastPrice > lastPcUp)
                    {
                        _tab.BuyAtLimit(GetVolume(_tab), lastPrice + Slippage.ValueInt * _tab.Security.PriceStep);
                    }
                }

                // Short
                if (Regime.ValueString != "OnlyLong")
                {
                    if (lastPrice < lastPcDown)
                    {
                        _tab.SellAtLimit(GetVolume(_tab), lastPrice - Slippage.ValueInt * _tab.Security.PriceStep);
                    }
                }
            }
        }

КОНЕЦ КОДА

Стандартный вход на свечках. Трейлинг стоп по ленте сделок. Микроменеджмент позиций в OsEngine#10 

  1. Если параметр Regime в положении Off, выходим из метода.
  2. Если данные по индикатору не начали формироваться, выходим из метода.
  3. Если кол-во данных в индикаторе меньше, чем длинна, указанная для его расчёта, выходим из метода.
  4. Если параметр Regime в положении OnlyClosePosition, выходим из метода.
  5. Запрашиваем текущие открытые позиции.
  6. Заходим в логику открытия позиции, только если позиций нет.
  7. Запрашиваем переменные, нужные для дальнейших расчётов.
  8. Входим в позицию лонг, если цена пробила ценовой канал вверх.
  9. Входим в позицию шорт, если цена пробила ценовой канал вниз.

 

5. Событие появления новой сделки в ленте сделок. Выставление стопа.

КОД

private void _tab_NewTickEvent(Trade trade)
        {
            if (Regime.ValueString == "Off")
            {
                return;
            }

            List openPositions = _tab.PositionsOpenAll;

            if (openPositions == null
                || openPositions.Count == 0)
            {
                return;
            }

            Position myPos = openPositions[0];

            if(myPos.State != PositionStateType.Open)
            {
                return;
            }

            decimal stopPrice = 0;
            decimal orderPrice = 0;

            if (myPos.Direction == Side.Buy)
            {
                stopPrice = trade.Price - (trade.Price * (TrailStopPercent.ValueDecimal/100));
                orderPrice = stopPrice - Slippage.ValueInt * _tab.Security.PriceStep;
            }
            else if(myPos.Direction == Side.Sell)
            {
                stopPrice = trade.Price + (trade.Price * (TrailStopPercent.ValueDecimal / 100));
                orderPrice = stopPrice + Slippage.ValueInt * _tab.Security.PriceStep;
            }

            _tab.CloseAtTrailingStop(myPos,stopPrice,orderPrice);

        }

КОНЕЦ КОДА

Стандартный вход на свечках. Трейлинг стоп по ленте сделок. Микроменеджмент позиций в OsEngine#10 

  1. Если параметр Regime в положении Off, выходим из метода.
  2. Запрашиваем текущие открытые позиции.
  3. Если открытых позиций нет, выходим из метода.
  4. Берём открытую позицию из массива всех открытых позиций.
  5. Если статус позиции не равен Open, т.е. она ещё не до конца открыта или уже закрывается, ничего не делаем.
  6. Создаём переменные для стоп уровня и цены выставления ордера.
  7. Рассчитываем цену стопа и ордера для него для позиции типа BUY (лонг).
  8. Рассчитываем цену стопа и ордера для него для позиции типа SELL (шорт).
  9. Вызываем у источника метод для перевыставления трейлинг стопа.

Удачных алгоритмов!

Комментарии открыты для друзей!

Стандартный вход на свечках. Трейлинг стоп по ленте сделок. Микроменеджмент позиций в OsEngine#10

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

Стандартный вход на свечках. Трейлинг стоп по ленте сделок. Микроменеджмент позиций в OsEngine#10