Auf GitHub ansehen

Reine Martingale-Strategie

Diese Strategie implementiert ein einfaches Martingale-System. Sie eröffnet Trades in einer zufälligen Richtung und verdoppelt nach jedem Verlust-Trade die Positionsgröße sowie die Stop/Take-Distanz. Nach einem Gewinn-Trade wird auf das ursprüngliche Volumen und die ursprüngliche Distanz zurückgesetzt.

Der Ansatz setzt darauf, dass der Preis letztendlich zur Profitabilität zurückkehrt, aber das Risiko wächst exponentiell. Nur auf liquiden Instrumenten mit engen Spreads verwenden.

Details

  • Einstiegskriterien:
    • Keine offene Position: zufällig kaufen oder verkaufen beim Kerzenschluss.
  • Long/Short: Beide.
  • Ausstiegskriterien:
    • Schließen, wenn sich der Preis um die konfigurierte Distanz zugunsten oder gegen die Position bewegt.
  • Stops: Virtuelle Stop-Loss- und Take-Profit-Aufträge, die von der Strategie verwaltet werden.
  • Filter:
    • Keine.
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>
/// Momentum strategy with EMA trend filter.
/// </summary>
public class PureMartingaleStrategy : Strategy
{
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevClose;
	private decimal _prevPrevClose;
	private int _barCount;

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

	public PureMartingaleStrategy()
	{
		_emaPeriod = Param(nameof(EmaPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("EMA Period", "EMA trend period", "Indicators");
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candles for trade timing", "General");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
		=> [(Security, CandleType)];

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevClose = 0;
		_prevPrevClose = 0;
		_barCount = 0;
	}

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

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		SubscribeCandles(CandleType).Bind(ema, ProcessCandle).Start();
	}

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

		var close = candle.ClosePrice;
		_barCount++;

		if (_barCount >= 3)
		{
			// Two consecutive rising closes above EMA => buy
			if (close > _prevClose && _prevClose > _prevPrevClose && close > emaValue && Position <= 0)
			{
				if (Position < 0) BuyMarket();
				BuyMarket();
			}
			// Two consecutive falling closes below EMA => sell
			else if (close < _prevClose && _prevClose < _prevPrevClose && close < emaValue && Position >= 0)
			{
				if (Position > 0) SellMarket();
				SellMarket();
			}
		}

		_prevPrevClose = _prevClose;
		_prevClose = close;
	}
}