Alexav D1 Profit GBPUSD — это дневная стратегия пробоя, конвертированная из советника MetaTrader 4 Alexav_d1_profit_gbpusd.mq4. Алгоритм работает на дневных свечах GBP/USD и оценивает завершившуюся сессию один раз в день (со вторника по пятницу). Моментум подтверждается при помощи RSI и MACD, а уровни стоп-лоссов и поэтапных тейк-профитов рассчитываются на основе ATR.
Логика торговли
Подготовка индикаторов
Две EMA одинакового периода прикладываются к максимумам и минимумам дневных свечей, формируя ориентиры для пробоя вверх и вниз.
RSI с периодом 10 измеряет силу импульса; экстремальные значения временно блокируют новые сделки в том же направлении.
MACD (5/24/14) анализирует ускорение, сравнивая два последних значения гистограммы.
ATR (28) задаёт единицу волатильности для расчёта стопов и целей.
Фильтр по дням недели
Проверка условий проводится один раз для каждой завершённой дневной свечи со вторника по пятницу. Понедельник и выходные пропускаются.
Условия входа в лонг
Предыдущая дневная свеча закрылась выше EMA по максимумам, рассчитанной два дня назад.
RSI предыдущей свечи выше уровня допуска (по умолчанию 60), но ниже верхнего предела (80).
MACD либо находился ниже нуля два дня назад, либо показал достаточное положительное ускорение относительно предыдущего значения.
Если открытие предыдущей свечи опускается ниже EMA по максимумам, запрет на новые покупки снимается.
Условия входа в шорт
Зеркальные условия: используется EMA по минимумам, нижние уровни RSI (39 / 25) и аналогичный фильтр ускорения MACD.
Управление позициями
При выполнении условий стратегия открывает пакет из четырёх рыночных ордеров (каждый с объёмом Volume):
Стоп-лосс: единый защитный стоп на расстоянии ATR * AtrStopMultiplier (по умолчанию 1.6) от цены входа.
Тейк-профит: цель для i-го ордера равна AtrTargetMultiplier * (1 + i / 2) ATR, что воспроизводит уровни 1.0, 1.5, 2.0 и 2.5 ATR из оригинального советника.
Разрешение конфликтов: перед открытием нового пакета противоположные позиции закрываются; запуск длинного пакета сбрасывает активность короткого и наоборот.
Контроль позиций ведётся по завершённым свечам. Если минимум дня достигает стопа — соответствующий лонг закрывается по рынку; достижение цели по максимуму также фиксирует прибыль. Для шортов используется максимум дня для стопа и минимум для тейк-профита.
Параметры
Параметр
Описание
Значение по умолчанию
CandleType
Основной ряд свечей (по умолчанию дневной).
1 день
MaPeriod
Период EMA по максимумам и минимумам.
6
RsiPeriod
Период RSI для фильтра импульса.
10
AtrPeriod
Период ATR для расчёта стопов и целей.
28
AtrStopMultiplier
Множитель ATR для стоп-лосса.
1.6
AtrTargetMultiplier
Базовый множитель ATR для тейк-профитов.
1.0
RsiUpperLevel
Минимальный RSI для подтверждения покупок.
60
RsiUpperLimit
Верхний предел RSI, блокирующий покупки.
80
RsiLowerLevel
Минимальный RSI для подтверждения продаж.
39
RsiLowerLimit
Нижний предел RSI, блокирующий продажи.
25
FastMaPeriod
Быстрый EMA MACD.
5
SlowMaPeriod
Медленный EMA MACD.
24
SignalMaPeriod
EMA сигнальной линии MACD.
14
MacdDiffBuy
Минимальное ускорение MACD для покупок.
0.5
MacdDiffSell
Минимальное ускорение MACD для продаж.
0.15
Перед запуском задайте свойство Volume, чтобы определить объём каждой сделки.
Дополнительно
Перенос сохраняет ключевую особенность оригинала — единственную проверку условий в день.
Для корректного бэктеста используйте дневные данные GBP/USD.
Стопы и цели контролируются по экстремумам дневных свечей; внутридневные всплески, не отразившиеся в дневном диапазоне, останутся незамеченными.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Alexav D1 Profit breakout strategy.
/// Buys when price breaks above EMA and RSI is rising.
/// Sells when price breaks below EMA and RSI is falling.
/// </summary>
public class AlexavD1ProfitGbpUsdBreakoutStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose;
private decimal _prevEma;
private decimal _prevRsi;
private bool _hasPrev;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public AlexavD1ProfitGbpUsdBreakoutStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetDisplay("EMA Period", "EMA period", "Indicators");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetDisplay("RSI Period", "RSI period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = 0m;
_prevEma = 0m;
_prevRsi = 0m;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, rsi, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue, decimal rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
if (!_hasPrev)
{
_prevClose = close;
_prevEma = emaValue;
_prevRsi = rsiValue;
_hasPrev = true;
return;
}
// Breakout above EMA with rising RSI
if (_prevClose <= _prevEma && close > emaValue && rsiValue > _prevRsi && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Breakout below EMA with falling RSI
else if (_prevClose >= _prevEma && close < emaValue && rsiValue < _prevRsi && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevClose = close;
_prevEma = emaValue;
_prevRsi = rsiValue;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class alexav_d1_profit_gbp_usd_breakout_strategy(Strategy):
"""Alexav D1 Profit breakout strategy.
Buys when price breaks above EMA and RSI is rising.
Sells when price breaks below EMA and RSI is falling."""
def __init__(self):
super(alexav_d1_profit_gbp_usd_breakout_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 20) \
.SetDisplay("EMA Period", "EMA period", "Indicators")
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_close = 0.0
self._prev_ema = 0.0
self._prev_rsi = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def EmaPeriod(self):
return self._ema_period.Value
@property
def RsiPeriod(self):
return self._rsi_period.Value
def OnReseted(self):
super(alexav_d1_profit_gbp_usd_breakout_strategy, self).OnReseted()
self._prev_close = 0.0
self._prev_ema = 0.0
self._prev_rsi = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(alexav_d1_profit_gbp_usd_breakout_strategy, self).OnStarted2(time)
self._has_prev = False
ema = ExponentialMovingAverage()
ema.Length = self.EmaPeriod
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, rsi, self._process_candle).Start()
def _process_candle(self, candle, ema_value, rsi_value):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
ema_val = float(ema_value)
rsi_val = float(rsi_value)
if not self._has_prev:
self._prev_close = close
self._prev_ema = ema_val
self._prev_rsi = rsi_val
self._has_prev = True
return
# Breakout above EMA with rising RSI
if self._prev_close <= self._prev_ema and close > ema_val and rsi_val > self._prev_rsi and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Breakout below EMA with falling RSI
elif self._prev_close >= self._prev_ema and close < ema_val and rsi_val < self._prev_rsi and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_close = close
self._prev_ema = ema_val
self._prev_rsi = rsi_val
def CreateClone(self):
return alexav_d1_profit_gbp_usd_breakout_strategy()