Открыть на GitHub

Стратегия Elderv30aug05v

Общее описание

Elderv30aug05v — порт советника MetaTrader 4 с тем же названием. Алгоритм сочетает два фильтра MACD на часовом таймфрейме и два стохастика на 15-минутных свечах. Торговля и управление выходами выполняются на минутных свечах, что повторяет тиковую логику оригинального MQL-скрипта. Стратегия держит не более одной позиции одновременно и опирается на динамические трейлинг-стопы вместо фиксированных тейк-профитов.

Используемые данные и индикаторы

  • Основной MACD (13/30/9, часовые свечи). Для лонга требуется, чтобы значение росло, а предыдущая величина оставалась ниже нуля.
  • Дополнительный MACD (14/56/9, часовые свечи). Для шорта необходимо снижение текущего значения при положительном предыдущем.
  • Быстрый стохастик (%K=2, %D=3, сглаживание=3, 15-минутные свечи). Лонг разрешён только если %K ниже порога LongStochasticThreshold (по умолчанию 36) и растёт относительно предыдущего бара.
  • Медленный стохастик (%K=1, %D=3, сглаживание=3, 15-минутные свечи). Для шорта %K должен быть выше ShortStochasticThreshold (по умолчанию 66) и снижаться по сравнению с предыдущим значением.
  • Минутные свечи обеспечивают подтверждение пробоя и служат для сопровождения позиции.

Все индикаторы обрабатывают только закрытые свечи через вызовы SubscribeCandles().Bind()/BindEx(), что соответствует рекомендациям по высокоуровневому API StockSharp.

Правила входа

Условия для покупки

  1. Основной MACD растёт, а его предыдущее значение ниже нуля.
  2. Быстрый стохастик находится ниже LongStochasticThreshold и выше предыдущего значения.
  3. Цена закрытия текущей минутной свечи выше максимума предыдущей минутной свечи.

Условия для продажи

  1. Дополнительный MACD падает, а его прошлое значение выше нуля.
  2. Медленный стохастик находится выше ShortStochasticThreshold и ниже предыдущего значения.
  3. Цена закрытия текущей минутной свечи ниже минимума предыдущей минутной свечи.

Если позиция уже открыта, новые сигналы игнорируются до закрытия текущей сделки по стопу или трейлингу.

Правила выхода

  • Начальный стоп-лосс: при входе фиксируется цена открытия плюс/минус LongStopLoss или ShortStopLoss, умноженные на PriceStep инструмента. При отсутствии шага цены используется запасное значение 0.0001.
  • Трейлинг-стоп: когда цена проходит как минимум LongTrailingStop или ShortTrailingStop пунктов в сторону позиции, стоп переносится за ценой закрытия текущей свечи. Для лонга стоп двигается вверх, для шорта — вниз.
  • Если диапазон свечи касается сохранённого стоп-уровня, позиция закрывается рыночной заявкой.

Тейк-профит не применяется, что полностью повторяет оригинальную реализацию.

Параметры

Параметр Значение по умолчанию Описание
Volume 0.1 Объём сделки для рыночных заявок.
LongStopLoss 17 Дистанция стоп-лосса для лонгов (в пунктах).
ShortStopLoss 46 Дистанция стоп-лосса для шортов (в пунктах).
LongTrailingStop 18 Шаг трейлинг-стопа для лонгов.
ShortTrailingStop 22 Шаг трейлинг-стопа для шортов.
LongStochasticThreshold 36 Максимальное значение быстрого стохастика для входа в лонг.
ShortStochasticThreshold 66 Минимальное значение медленного стохастика для входа в шорт.
BaseCandleType TimeFrame(1m) Таймфрейм для исполнения и сопровождения.
StochasticCandleType TimeFrame(15m) Таймфрейм для обоих стохастиков.
MacdCandleType TimeFrame(1h) Таймфрейм для обоих MACD.
MacdFastPeriod / MacdSlowPeriod / MacdSignalPeriod 13 / 30 / 9 Периоды основного MACD.
AltMacdFastPeriod / AltMacdSlowPeriod / AltMacdSignalPeriod 14 / 56 / 9 Периоды дополнительного MACD.
StochasticFastKPeriod / StochasticFastDPeriod / StochasticFastSmooth 2 / 3 / 3 Параметры быстрого стохастика.
StochasticSlowKPeriod / StochasticSlowDPeriod / StochasticSlowSmooth 1 / 3 / 3 Параметры медленного стохастика.

Дополнительные замечания

  • Стратегия подходит для любых инструментов с минутными свечами и корректным PriceStep.
  • Трейлинг-стопы реализованы внутри стратегии, биржевые защитные заявки не выставляются.
  • Обработка ведётся только по завершённым свечам, что исключает перерисовку и соответствует логике оригинального советника.

Источник

  • Файл: MQL/7674/Elderv30aug05v.mq4
  • Платформа: MetaTrader 4.
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>
/// Elder strategy - EMA trend + Momentum confirmation.
/// Buys when EMA is rising and momentum crosses above zero.
/// Sells when EMA is falling and momentum crosses below zero.
/// </summary>
public class Elderv30aug05vStrategy : Strategy
{
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<int> _momentumPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevEma;
	private decimal _prevMomentum;
	private bool _hasPrev;

	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
	public int MomentumPeriod { get => _momentumPeriod.Value; set => _momentumPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public Elderv30aug05vStrategy()
	{
		_emaPeriod = Param(nameof(EmaPeriod), 13)
			.SetDisplay("EMA Period", "EMA period for trend", "Indicators");

		_momentumPeriod = Param(nameof(MomentumPeriod), 10)
			.SetDisplay("Momentum Period", "Momentum period", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
	protected override void OnReseted() { base.OnReseted(); _prevEma = 0m; _prevMomentum = 0m; _hasPrev = false; }

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_hasPrev = false;

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		var momentum = new Momentum { Length = MomentumPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(ema, momentum, ProcessCandle)
			.Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal ema, decimal momentum)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!_hasPrev)
		{
			_prevEma = ema;
			_prevMomentum = momentum;
			_hasPrev = true;
			return;
		}

		var emaRising = ema > _prevEma;
		var emaFalling = ema < _prevEma;
		var momCrossUp = _prevMomentum <= 0 && momentum > 0;
		var momCrossDown = _prevMomentum >= 0 && momentum < 0;

		// Buy: EMA rising + momentum crosses above zero
		if (emaRising && momCrossUp && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// Sell: EMA falling + momentum crosses below zero
		else if (emaFalling && momCrossDown && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevEma = ema;
		_prevMomentum = momentum;
	}
}