El Sistema de contracanal Donchain reproduce el asesor experto MetaTrader 4 de 2005 de Michal Rutka. Vigila los giros en un canal Donchian de 20 días calculado sobre velas diarias. Cuando la banda inferior gira hacia arriba, la estrategia supone que los vendedores no lograron llevar el precio a nuevos mínimos y compran en la siguiente sesión en el mercado. Cuando la banda superior gira hacia abajo, la estrategia lo interpreta como una pérdida de impulso en los repuntes y vende en corto en el mercado. Las paradas de protección siempre están alineadas con la banda Donchian opuesta para que las salidas reflejen la lógica original de gestión de paradas.
Sólo se permite una entrada cada 24 horas, coincidiendo con la regla del artículo que restringe el sistema a como máximo un pedido por día. Esta implementación utiliza el API de alto nivel de StockSharp con enlaces de indicadores para que los valores de Donchian lleguen junto con cada vela completa.
Lógica de trading
Suscríbase al CandleType configurado (diario por defecto) y evalúe un indicador DonchianChannels con el ChannelPeriod seleccionado.
Cada vez que se acaba una vela:
Si hay una posición larga abierta, mueva el nivel de parada a la banda inferior actual cuando suba y salga si el mínimo de la vela toca ese nivel.
Si hay una posición corta abierta, mueva el nivel de parada a la banda superior actual cuando caiga y salga si el máximo de la vela toca ese nivel.
Si no hay ninguna posición, omita las entradas cuando la última operación ocurrió hace menos de TradeCooldown.
Vaya en largo cuando la banda inferior Donchian de la vela anterior sea más alta que la vela anterior, lo que indica un repunte en el piso del canal. Establezca la parada inicial en la banda inferior actual.
Vaya en corto cuando la banda superior Donchian de la vela anterior sea más baja que la vela anterior, lo que indica una caída en el techo del canal. Establezca la parada inicial en la banda superior actual.
Continúe siguiendo el stop a lo largo de las bandas hasta que el precio se invierta a través de ellas, lo que cierra la posición.
Parámetros
Nombre
Predeterminado
Descripción
Volume
1
Tamaño del pedido para entradas largas y cortas.
ChannelPeriod
20
Número de velas utilizadas para calcular las bandas superior e inferior Donchian.
TradeCooldown
1 day
Período mínimo de espera antes de que se permita una nueva entrada.
CandleType
Daily
Serie de velas sobre las que se calcula el Canal Donchian.
Indicadores y datos
Donchian Canales: proporciona los límites de canal superior e inferior utilizados para la detección de cambios de tendencia y para paradas dinámicas.
Velas diarias (predeterminado): tiempos de cierre de suministro necesarios para el tiempo de reutilización de 24 horas y para evaluar los turnos del indicador.
Notas de implementación
La estrategia utiliza BindEx para recibir un DonchianChannelsValue escrito en el controlador de velas, lo que garantiza que ambas bandas estén disponibles simultáneamente.
Las paradas se simulan monitoreando los máximos y mínimos de las velas con respecto al valor de la banda almacenado, tal como el EA original actualizaba su stop-loss en cada nueva barra.
El temporizador de recuperación se actualiza solo con nuevas entradas, reflejando el script fuente que impedía múltiples entradas dentro del mismo día de negociación.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Donchian counter-channel system.
/// Counter-trend: buys when lower channel turns up (reversal from support).
/// Sells when upper channel turns down (reversal from resistance).
/// </summary>
public class DonchainCounterChannelSystemStrategy : Strategy
{
private readonly StrategyParam<int> _channelPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevHigh;
private decimal _prevLow;
private decimal _prevPrevHigh;
private decimal _prevPrevLow;
private int _barCount;
public int ChannelPeriod { get => _channelPeriod.Value; set => _channelPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public DonchainCounterChannelSystemStrategy()
{
_channelPeriod = Param(nameof(ChannelPeriod), 20)
.SetDisplay("Channel Period", "Donchian channel lookback", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevHigh = 0m; _prevLow = 0m; _prevPrevHigh = 0m; _prevPrevLow = 0m; _barCount = 0; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_barCount = 0;
var highest = new Highest { Length = ChannelPeriod };
var lowest = new Lowest { Length = ChannelPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highest, lowest, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal highest, decimal lowest)
{
if (candle.State != CandleStates.Finished)
return;
_barCount++;
if (_barCount < 3)
{
_prevPrevHigh = _prevHigh;
_prevPrevLow = _prevLow;
_prevHigh = highest;
_prevLow = lowest;
return;
}
// Lower band turning up = support holding = buy signal
var lowerTurningUp = lowest > _prevLow && _prevLow <= _prevPrevLow;
// Upper band turning down = resistance holding = sell signal
var upperTurningDown = highest < _prevHigh && _prevHigh >= _prevPrevHigh;
if (lowerTurningUp && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
else if (upperTurningDown && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevPrevHigh = _prevHigh;
_prevPrevLow = _prevLow;
_prevHigh = highest;
_prevLow = lowest;
}
}