Auf GitHub ansehen

3Commas Turtle-Strategie

Vereinfachtes Turtle-Ausbruchssystem mit Donchian-Kanälen. Kauft bei Ausbrüchen über den schnellen Kanal, wenn der Preis auch über dem langsamen Kanal liegt, und verkauft bei Ausbrüchen unter den schnellen Kanal mit Bestätigung durch den langsamen Kanal. Ausstiege erfolgen, wenn der Preis den Austrittskanal in der entgegengesetzten Richtung kreuzt.

Details

  • Einstiegskriterien: Ausbruch des schnellen Kanals mit Bestätigung durch den langsamen Kanal.
  • Long/Short: Beide Richtungen.
  • Ausstiegskriterien: Preis kreuzt Austrittskanal.
  • Stops: Kanalbasiert.
  • Standardwerte:
    • PeriodFast = 20
    • PeriodSlow = 20
    • PeriodExit = 10
    • CandleType = TimeSpan.FromMinutes(1)
  • Filter:
    • Kategorie: Trend
    • Richtung: Beide
    • Indikatoren: Donchian-Kanäle
    • Stops: Ja
    • Komplexität: Mittel
    • Zeitrahmen: Intraday
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikolevel: Mittel
using System;
using System.Linq;
using System.Collections.Generic;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Simplified turtle breakout strategy.
/// </summary>
public class ThreeCommasTurtleStrategy : Strategy
{
	private readonly StrategyParam<int> _periodFast;
	private readonly StrategyParam<int> _periodSlow;
	private readonly StrategyParam<int> _periodExit;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevUpperFast;
	private decimal _prevLowerFast;
	private decimal _prevClose;

	public int PeriodFast
	{
		get => _periodFast.Value;
		set => _periodFast.Value = value;
	}

	public int PeriodSlow
	{
		get => _periodSlow.Value;
		set => _periodSlow.Value = value;
	}

	public int PeriodExit
	{
		get => _periodExit.Value;
		set => _periodExit.Value = value;
	}

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

	public ThreeCommasTurtleStrategy()
	{
		_periodFast = Param(nameof(PeriodFast), 10)
			.SetDisplay("Period Fast", "Fast channel period", "Channels");
		_periodSlow = Param(nameof(PeriodSlow), 15)
			.SetDisplay("Period Slow", "Slow channel period", "Channels");
		_periodExit = Param(nameof(PeriodExit), 5)
			.SetDisplay("Period Exit", "Exit channel period", "Channels");
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use", "General");
	}

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

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevUpperFast = 0m;
		_prevLowerFast = 0m;
		_prevClose = 0m;
	}

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

		_prevUpperFast = 0m;
		_prevLowerFast = 0m;
		_prevClose = 0m;

		var upperFast = new Highest { Length = PeriodFast };
		var lowerFast = new Lowest { Length = PeriodFast };
		var upperSlow = new Highest { Length = PeriodSlow };
		var lowerSlow = new Lowest { Length = PeriodSlow };
		var upperExit = new Highest { Length = PeriodExit };
		var lowerExit = new Lowest { Length = PeriodExit };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(upperFast, lowerFast, upperSlow, lowerSlow, upperExit, lowerExit, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal upFast, decimal lowFast, decimal upSlow, decimal lowSlow, decimal upExit, decimal lowExit)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (_prevClose == 0)
		{
			_prevUpperFast = upFast;
			_prevLowerFast = lowFast;
			_prevClose = candle.ClosePrice;
			return;
		}

		if (candle.ClosePrice > _prevUpperFast && Position <= 0)
		{
			BuyMarket();
		}
		else if (candle.ClosePrice < _prevLowerFast && Position >= 0)
		{
			SellMarket();
		}
		else if (Position > 0 && candle.ClosePrice < lowExit)
			SellMarket();
		else if (Position < 0 && candle.ClosePrice > upExit)
			BuyMarket();

		_prevUpperFast = upFast;
		_prevLowerFast = lowFast;
		_prevClose = candle.ClosePrice;
	}
}