Ver en GitHub

Estrategia 3Commas Turtle

Sistema de ruptura simplificado al estilo Turtle usando canales Donchian. Compra en rupturas por encima del canal rápido cuando el precio también está por encima del canal lento, y vende en caídas por debajo del canal rápido con confirmación del canal lento. Las salidas ocurren cuando el precio cruza el canal de salida en la dirección opuesta.

Detalles

  • Criterios de entrada: Ruptura del canal rápido con confirmación del canal lento.
  • Largo/Corto: Ambas direcciones.
  • Criterios de salida: El precio cruza el canal de salida.
  • Stops: Basados en el canal.
  • Valores predeterminados:
    • PeriodFast = 20
    • PeriodSlow = 20
    • PeriodExit = 10
    • CandleType = TimeSpan.FromMinutes(1)
  • Filtros:
    • Categoría: Tendencia
    • Dirección: Ambos
    • Indicadores: Canales Donchian
    • Stops: Sí
    • Complejidad: Intermedio
    • Marco temporal: Intradía
    • Estacionalidad: No
    • Redes neuronales: No
    • Divergencia: No
    • Nivel de riesgo: Medio
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;
	}
}