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= 20PeriodSlow= 20PeriodExit= 10CandleType= 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;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class three_commas_turtle_strategy(Strategy):
def __init__(self):
super(three_commas_turtle_strategy, self).__init__()
self._period_fast = self.Param("PeriodFast", 10) \
.SetDisplay("Period Fast", "Fast channel period", "Channels")
self._period_slow = self.Param("PeriodSlow", 15) \
.SetDisplay("Period Slow", "Slow channel period", "Channels")
self._period_exit = self.Param("PeriodExit", 5) \
.SetDisplay("Period Exit", "Exit channel period", "Channels")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._prev_upper_fast = 0.0
self._prev_lower_fast = 0.0
self._prev_close = 0.0
@property
def period_fast(self):
return self._period_fast.Value
@property
def period_slow(self):
return self._period_slow.Value
@property
def period_exit(self):
return self._period_exit.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(three_commas_turtle_strategy, self).OnReseted()
self._prev_upper_fast = 0.0
self._prev_lower_fast = 0.0
self._prev_close = 0.0
def OnStarted2(self, time):
super(three_commas_turtle_strategy, self).OnStarted2(time)
upper_fast = Highest()
upper_fast.Length = self.period_fast
lower_fast = Lowest()
lower_fast.Length = self.period_fast
upper_slow = Highest()
upper_slow.Length = self.period_slow
lower_slow = Lowest()
lower_slow.Length = self.period_slow
upper_exit = Highest()
upper_exit.Length = self.period_exit
lower_exit = Lowest()
lower_exit.Length = self.period_exit
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(upper_fast, lower_fast, upper_slow, lower_slow, upper_exit, lower_exit, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def on_process(self, candle, up_fast, low_fast, up_slow, low_slow, up_exit, low_exit):
if candle.State != CandleStates.Finished:
return
if self._prev_close == 0:
self._prev_upper_fast = up_fast
self._prev_lower_fast = low_fast
self._prev_close = candle.ClosePrice
return
if candle.ClosePrice > self._prev_upper_fast and self.Position <= 0:
self.BuyMarket()
elif candle.ClosePrice < self._prev_lower_fast and self.Position >= 0:
self.SellMarket()
elif self.Position > 0 and candle.ClosePrice < low_exit:
self.SellMarket()
elif self.Position < 0 and candle.ClosePrice > up_exit:
self.BuyMarket()
self._prev_upper_fast = up_fast
self._prev_lower_fast = low_fast
self._prev_close = candle.ClosePrice
def CreateClone(self):
return three_commas_turtle_strategy()