Открыть на GitHub

Стратегия Simple Martingale Template

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

Данная стратегия переносит логику MT4-советника «Simple Martingale Template» в инфраструктуру StockSharp. Анализируются завершённые свечи выбранного таймфрейма. Для генерации сигналов используются две простые скользящие средние (SMA) и фильтр пробоя: закрытие предыдущей свечи должно выйти за максимум или минимум свечи двумя барами ранее. Объём позиции управляется по схеме мартингейла — после убыточного цикла объём умножается, после прибыльного цикла возвращается к базовому значению.

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

  1. Подписка на свечи таймфрейма CandleType. В расчётах участвуют только закрытые свечи.
  2. Расчёт быстрых и медленных SMA по цене закрытия.
  3. Покупка открывается, если:
    • закрытие последней свечи выше быстрой SMA,
    • быстрая SMA выше медленной,
    • на предыдущей свече быстрая SMA была ниже медленной,
    • закрытие последней свечи выше максимума свечи двумя барами ранее.
  4. Продажа открывается при зеркально противоположных условиях и закрытии ниже минимума свечи двумя барами ранее.
  5. При появлении сигнала и отсутствии позиции/активных заявок стратегия отправляет рыночный ордер с текущим объёмом мартингейла.
  6. Стоп-лосс и тейк-профит реализованы программно: после входа хранятся целевые цены, и при касании этих уровней по максимуму/минимуму новой свечи позиция закрывается рыночным ордером.
  7. После закрытия позиции анализируется изменение баланса портфеля:
    • рост баланса приводит к возврату объёма к BaseVolume;
    • падение баланса умножает предыдущий объём на Multiplier с учётом шага объёма инструмента.

Параметры

Название Описание
StopLossPoints Расстояние до защитного стопа в пунктах.
TakeProfitPoints Расстояние до тейк-профита в пунктах.
BaseVolume Базовый лот первого шага мартингейла.
Multiplier Множитель объёма после убыточной сделки.
FastPeriod Период быстрой SMA.
SlowPeriod Период медленной SMA.
CandleType Таймфрейм анализируемых свечей.

Управление капиталом

  • Изменение объёма происходит только при фиксации результата и отсутствии позиций; мелкие колебания (±0.01 денежной единицы) игнорируются.
  • Перед постановкой ордеров объём округляется к допустимому шагу, учитываются минимальные и максимальные ограничения инструмента.
  • Стоп и тейк контролируются по экстремумам свечей, что повторяет механику оригинального советника, использовавшего рыночные выходы.

Рекомендации по использованию

  • Подбирайте таймфрейм и инструмент так, чтобы SMA успели сформироваться (требуются как минимум два закрытых бара до запуска логики).
  • Значения StopLossPoints и TakeProfitPoints задаются в пунктах, поэтому их необходимо адаптировать к размеру шага цены выбранного инструмента.
  • Контролируйте агрессивность мартингейла: при больших множителях капитал требования быстро возрастают.
  • Стратегия вызывает StartProtection(), поэтому стандартные защитные механизмы StockSharp продолжают работать совместно.
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Simple Martingale Template strategy: SMA crossover with momentum confirmation.
/// Buys on fast SMA crossing above slow SMA, sells on crossing below.
/// </summary>
public class SimpleMartingaleTemplateStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }

	public SimpleMartingaleTemplateStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 5)
			.SetGreaterThanZero()
			.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 15)
			.SetGreaterThanZero()
			.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_hasPrev = false;
		var fast = new SimpleMovingAverage { Length = FastPeriod };
		var slow = new SimpleMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, ProcessCandle).Start();
	}

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

		if (_hasPrev)
		{
			if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
				BuyMarket();
			else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
				SellMarket();
		}
		else
		{
			if (fastValue > slowValue && Position <= 0)
				BuyMarket();
			else if (fastValue < slowValue && Position >= 0)
				SellMarket();
		}

		_prevFast = fastValue;
		_prevSlow = slowValue;
		_hasPrev = true;
	}
}