Открыть на GitHub

Стратегия Binary Wave StdDev

Стратегия суммирует сигналы от MA, MACD, CCI, Momentum, RSI и ADX с настраиваемыми весами. Сделки открываются по направлению итогового балла, если волатильность (стандартное отклонение) превышает порог. Стоп‑лосс и тейк‑профит в пунктах по желанию.

Детали

  • Условия входа:
    • Лонг: балл > 0 и StdDev >= EntryVolatility
    • Шорт: балл < 0 и StdDev >= EntryVolatility
  • Условия выхода:
    • Волатильность падает ниже ExitVolatility
  • Стопы: опционально через UseStopLoss и UseTakeProfit
  • Значения по умолчанию:
    • WeightMa = 1
    • WeightMacd = 1
    • WeightCci = 1
    • WeightMomentum = 1
    • WeightRsi = 1
    • WeightAdx = 1
    • MaPeriod = 13
    • FastMacd = 12
    • SlowMacd = 26
    • SignalMacd = 9
    • CciPeriod = 14
    • MomentumPeriod = 14
    • RsiPeriod = 14
    • AdxPeriod = 14
    • StdDevPeriod = 9
    • EntryVolatility = 1.5
    • ExitVolatility = 1
    • StopLossPoints = 1000
    • TakeProfitPoints = 2000
    • UseStopLoss = false
    • UseTakeProfit = false
    • CandleType = TimeSpan.FromHours(4).TimeFrame()
  • Фильтры:
    • Категория: Следование тренду
    • Направление: Обе стороны
    • Индикаторы: MA, MACD, CCI, Momentum, RSI, ADX, StandardDeviation
    • Стопы: Опционально
    • Сложность: Средняя
    • Таймфрейм: Среднесрочный
    • Сезонность: Нет
    • Нейросети: Нет
    • Дивергенция: Нет
    • Уровень риска: Средний
using System;
using System.Collections.Generic;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Binary Wave Standard Deviation strategy.
/// Combines multiple indicators with weights and uses volatility filter based on standard deviation.
/// </summary>
public class BinaryWaveStdDevStrategy : Strategy
{
	private readonly StrategyParam<decimal> _weightMa;
	private readonly StrategyParam<decimal> _weightCci;
	private readonly StrategyParam<decimal> _weightRsi;
	private readonly StrategyParam<int> _maPeriod;
	private readonly StrategyParam<int> _cciPeriod;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _stdDevPeriod;
	private readonly StrategyParam<DataType> _candleType;

	public decimal WeightMa { get => _weightMa.Value; set => _weightMa.Value = value; }
	public decimal WeightCci { get => _weightCci.Value; set => _weightCci.Value = value; }
	public decimal WeightRsi { get => _weightRsi.Value; set => _weightRsi.Value = value; }
	public int MaPeriod { get => _maPeriod.Value; set => _maPeriod.Value = value; }
	public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public int StdDevPeriod { get => _stdDevPeriod.Value; set => _stdDevPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public BinaryWaveStdDevStrategy()
	{
		_weightMa = Param(nameof(WeightMa), 1m)
			.SetDisplay("MA Weight", "Weight for moving average direction", "Weights");
		_weightCci = Param(nameof(WeightCci), 1m)
			.SetDisplay("CCI Weight", "Weight for CCI direction", "Weights");
		_weightRsi = Param(nameof(WeightRsi), 1m)
			.SetDisplay("RSI Weight", "Weight for RSI", "Weights");

		_maPeriod = Param(nameof(MaPeriod), 13)
			.SetDisplay("MA Period", "Moving average period", "Indicators");
		_cciPeriod = Param(nameof(CciPeriod), 14)
			.SetDisplay("CCI Period", "Lookback period for CCI", "Indicators");
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetDisplay("RSI Period", "Lookback for RSI", "Indicators");
		_stdDevPeriod = Param(nameof(StdDevPeriod), 9)
			.SetDisplay("StdDev Period", "Length of standard deviation", "Indicators");

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

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var ema = new ExponentialMovingAverage { Length = MaPeriod };
		var cci = new CommodityChannelIndex { Length = CciPeriod };
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var stdDev = new StandardDeviation { Length = StdDevPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(ema, cci, rsi, stdDev, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal emaValue, decimal cciValue, decimal rsiValue, decimal stdDevValue)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		var score = 0m;
		score += candle.ClosePrice > emaValue ? WeightMa : -WeightMa;
		score += cciValue > 0 ? WeightCci : -WeightCci;
		score += rsiValue > 50 ? WeightRsi : -WeightRsi;

		if (score > 0 && Position <= 0)
			BuyMarket();
		else if (score < 0 && Position >= 0)
			SellMarket();
	}
}