Форум устарел! Поддержка тут: https://t.me/osengine_official_support
Актуальные гайды здесь: https://smart-lab.ru/company/os_engine/blog/1024149.php
Трендовый робот на основе индикатора Bollinger
Трендовый робот на основе индикатора Bollinger.
Торговая логика робота:
Стратегия реверсивная.
Вход лонг : Закрытие свечки происходит выше верхнего значения индикатора Bollinger. Пробитие индикатора вверх.
Вход шорт: Закрытие свечки происходит ниже нижнего значения индикатора Bollinger. Пробитие индикатора вниз.
Выход из Лонга: Закрытие свечки происходит ниже нижнего значения индикатора Bollinger. Пробитие индикатора вниз.
Выход из Шорта: Закрытие свечки происходит выше верхнего значения индикатора Bollinger. Пробитие индикатора вверх.
Окно с настройками стратегии:
1. Режим. On - включен. Off - отключен; OnlyLong - входим только в лонг; OnlyShort - входим только в шорт; OnlyClosePosition - закрываем позиции.
2. Объем фиксированный - количество лотов на вход.
3. Проскальзывание - величина проскальзывания в пунктах.
Настройка индикатора:
Настройка Bollinger используемого в алгоритме робота
осуществляется как стандартная настройка и индикатора через меню настроек индикаторов при нажатии правой кнопки мыши на графике
Здравствуйте!
Решил переделать поведение робота на открытие/закрытие позиции при касании параболика. Подписался на событие
_tab.CandleUpdateEvent += LogicToUpdateLastCandle;
Сам метод выглядит так (добавил свои комментарии).
private void LogicToUpdateLastCandle(List<Candle> candles)
{
// если не торгуем, то выход
if (Regime == BotTradeRegime.Off) return;
// если баров меньше трёх, то выход
if (candles.Count < 3) return;
// берем открытие на предыдущем (закрытом) баре
decimal _prevOpen = candles[candles.Count - 2].Open;
// берем значение параболика на предыдущем (закрытом) баре
decimal _prevSAR = _sar.Values[_sar.Values.Count - 2];
// если открытие было выше параболика, то "тренд" вверх
Boolean upTrend = _prevOpen > _prevSAR;
// если текущий хай (активного бара) выше предыдущего параболика, то касание вверх
Boolean touchUp = candles[candles.Count - 1].High >= _prevSAR;
// если текущий лоу (активного бара) ниже предыдущего параболика, то касание вниз
Boolean touchDn = candles[candles.Count - 1].Low <= _prevSAR;
// касание вверх учитываем на "тренде" вниз
touchUp = touchUp && !upTrend;
// касание вниз учитываем на "тренде" вверх
touchDn = touchDn && upTrend;
// текущая позиция (0: отсутстсвует, 1: лонг, -1: шорт)
Int32 currentPos = 100;
// если открытых позиций нет или их кол-во равно нулю, то currentPos = 0
if ( _tab.PositionsOpenAll == null || _tab.PositionsOpenAll.Count == 0 ) currentPos = 0;
// последняя позиция
Position lastPos;
if (currentPos == 100)
{
// берем последнюю позицию
// и вот тут сомнения в правильности использования PositionsOpenAll
// может быть правильнее брать PositionsAll ??
lastPos = _tab.PositionsOpenAll[0];
// если позиция в процессе открытия или закрытия, то выход
if (lastPos.State == PositionStateType.Opening) return;
if (lastPos.State == PositionStateType.Closing) return;
// возвращаем в currentPos в зависимости от lastPos.Direction
currentPos = lastPos.Direction == Side.None ? 0 : lastPos.Direction == Side.Buy ? 1 : -1;
}
// если позиции нет
if (currentPos == 0) {
// если касание вверх и режим не только шорт, то купить по рынку
if (touchUp && Regime != BotTradeRegime.OnlyShort) _tab.BuyAtMarket(VolumeFix);
// если касание вниз и режим не только лонг, то продать по рынку
if (touchDn && Regime != BotTradeRegime.OnlyLong) _tab.SellAtMarket(VolumeFix);
return;
}
// если сейчас шорт и касание вверх
if (currentPos < 0 && touchUp ) {
// купить по рынку
_tab.BuyAtMarket(VolumeFix);
// если режим закрытия позиций или только шорт, то выход
if (Regime == BotTradeRegime.OnlyClosePosition) return;
if (Regime == BotTradeRegime.OnlyShort) return;
// еще купить по рынку
_tab.BuyAtMarket(VolumeFix);
return;
}
// если сейчас лонг и касание вниз
if (currentPos > 0 && touchDn ) {
// продать по рынку
_tab.SellAtMarket(VolumeFix);
// если режим закрытия позиций или только лонг, то выход
if (Regime == BotTradeRegime.OnlyClosePosition) return;
if (Regime == BotTradeRegime.OnlyLong) return;
// еще продать по рынку
_tab.SellAtMarket(VolumeFix);
return;
}
}
Пару раз сработало как положено, но в следующее касание робот начал кидать заявки в рынок, пока в транзакциях квика не появилось:
Превышено максимальное количество транзакций 30 в интервале 1 сек
Ошибка создания заявки. [GW][332] "Нехватка средств по лимитам клиента."
Подозреваю, что я где-то не разобрался со статусами позиций. Прошу помочь в этом вопросе. Спасибо заранее.
Цитата: Pherino
Здравствуйте!
Превышено максимальное количество транзакций 30 в интервале 1 сек
Ошибка создания заявки. [GW][332] "Нехватка средств по лимитам клиента."Подозреваю, что я где-то не разобрался со статусами позиций. Прошу помочь в этом вопросе. Спасибо заранее.
Не вижу ошибки по тому что есть. Надо ж разбираться сидеть. Переделывайте. Для начала откажитесь от своего С++ стайла. Там же есть перечисления нормальные.
Фрагмент определения текущей позиции currentPos заменил на такой:
// получить все позиции
List<Position> positions = _tab.PositionsAll;
// если пусто, то currentPos = 0
if (positions == null || positions.Count == 0) currentPos = 0;
else {
// если есть открывающиеся позиции, то выход
if (_tab.PositionsAll.FindAll(position => position.State == PositionStateType.Opening) != null) return;
// если есть закрывающиеся позиции, то выход
if (_tab.PositionsAll.FindAll(position => position.State == PositionStateType.Closing) != null) return;
// получить открытые позиии
positions = _tab.PositionsAll.FindAll(position => position.State == PositionStateType.Open);
// если открытых нет, то currentPos = 0
if (positions == null || positions.Count == 0) currentPos = 0;
else {
// взять первую открытую позицию
Position lastPos = positions[0];
currentPos = lastPos.Direction == Side.None ? 0 : lastPos.Direction == Side.Buy ? 1 : -1;
}
}
Пока наблюдаю.
ООО «ВАН ТЕХНОЛОГИИ»т: +7 953 769 56 45
* Торговля на финансовых рынках связана с риском, который лежит на Вас.
* Ничто из написанного на сайте o-s-a.net не является рекомендацией.
* Если Вы этого не понимаете, не читайте этот сайт, ничего не покупайте.