Открыть на GitHub

Стратегия BrainTrend2 + AbsolutelyNoLagLWMA MMRec

Обзор

Стратегия воспроизводит советник MetaTrader Exp_BrainTrend2_AbsolutelyNoLagLwma_MMRec, объединяя два блока сигналов: трендовый блок BrainTrend2 и адаптивный фильтр AbsolutelyNoLagLWMA. Каждый блок может открывать и закрывать позиции в соответствии со своими разрешениями, как в MMRec-шаблоне оригинала. Заявки исполняются рыночными ордерами через высокоуровневый API StockSharp с настраиваемым объёмом.

Логика торговли

Блок BrainTrend2

  • Формирует плавающий уровень на основе взвешенного истинного диапазона (ATR).
  • Направление («river») меняется, когда свеча пробивает буфер более чем на 0.7 * ATR.
  • Бычья свеча внутри восходящего режима открывает лонг (если разрешено) и закрывает шорт.
  • Медвежья свеча внутри нисходящего режима открывает шорт (если разрешено) и закрывает лонг.
  • Параметр Brain Signal Shift позволяет сдвигать анализируемую свечу назад на несколько баров.

Блок AbsolutelyNoLagLWMA

  • Применяет два последовательных линейно взвешенных скользящих средних к выбранному источнику цены.
  • Цвет линии становится 2 при росте двойной LWMA, 0 при снижении и 1 при нейтральном состоянии.
  • Переход к цвету 2 даёт сигнал на покупку и (опционально) закрытие шортов; переход к цвету 0 даёт сигнал на продажу и (опционально) закрытие лонгов.
  • Сдвиг сигналов регулируется параметром Abs Signal Shift.

Управление позицией

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

Параметры

Группа Название Описание
BrainTrend2 Brain Candle Тип свечей для расчёта BrainTrend2.
BrainTrend2 Brain ATR Период ATR для внутренней логики BrainTrend2.
BrainTrend2 Brain Signal Shift Сдвиг сигналов BrainTrend2 по истории.
BrainTrend2 Brain Buy / Sell Разрешение на открытие лонгов/шортов блоком BrainTrend2.
BrainTrend2 Brain Close Buys / Close Sells Разрешение блоку BrainTrend2 закрывать существующие позиции.
AbsolutelyNoLag Abs Candle Тип свечей для фильтра LWMA.
AbsolutelyNoLag Abs Length Период LWMA.
AbsolutelyNoLag Abs Price Источник цены (аналог перечисления Applied_price_ в MQL).
AbsolutelyNoLag Abs Signal Shift Сдвиг сигналов LWMA по истории.
AbsolutelyNoLag Abs Buy / Sell Разрешение на открытие лонгов/шортов блоком LWMA.
AbsolutelyNoLag Abs Close Buys / Close Sells Разрешение LWMA закрывать позиции.
AbsolutelyNoLag Abs Shift Постоянный сдвиг значения LWMA.
General Order Volume Базовый объём рыночных ордеров.

Примечания

  • Формулы ATR и LWMA перенесены из MQL-версии, включая треугольное взвешивание и полный список источников цены.
  • В свечах StockSharp нет данных о спреде, поэтому истинный диапазон рассчитывается только по ценам, что эквивалентно нулевому спреду.
  • Одновременные позиции с разными magic-номерами сведены к одной нетто-позиции, что соответствует модели портфеля в StockSharp.
using System;
using System.Collections.Generic;

using Ecng.Common;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// BrainTrend2 AbsolutelyNoLag LWMA MMRec strategy (simplified).
/// Uses RSI + EMA for trend detection with position recovery logic.
/// </summary>
public class BrainTrend2AbsolutelyNoLagLwmaMmrecStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _emaLength;

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public int EmaLength
	{
		get => _emaLength.Value;
		set => _emaLength.Value = value;
	}

	public BrainTrend2AbsolutelyNoLagLwmaMmrecStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Candles", "General");

		_rsiLength = Param(nameof(RsiLength), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Length", "RSI period", "Indicators");

		_emaLength = Param(nameof(EmaLength), 20)
			.SetGreaterThanZero()
			.SetDisplay("EMA Length", "EMA period", "Indicators");
	}

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

		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var ema = new ExponentialMovingAverage { Length = EmaLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, ema, (ICandleMessage candle, decimal rsiVal, decimal emaVal) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				var close = candle.ClosePrice;

				// Bullish: RSI above 55 and close above EMA
				if (rsiVal > 55 && close > emaVal && Position <= 0)
					BuyMarket();
				// Bearish: RSI below 45 and close below EMA
				else if (rsiVal < 45 && close < emaVal && Position >= 0)
					SellMarket();
			})
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, ema);
			DrawOwnTrades(area);
		}
	}
}