Estrategia Robot Danu
Estrategia que compara los niveles rápidos y lentos de ZigZag derivados de los máximos y mínimos de las velas. Se abre una posición corta cuando el nivel ZigZag rápido está por encima del lento. Se abre una posición larga cuando el nivel ZigZag rápido está por debajo del lento.
Detalles
- Criterios de entrada: Comparación de pivotes ZigZag rápidos y lentos.
- Largo/Corto: Ambos direcciones.
- Criterios de salida: Relación ZigZag opuesta.
- Stops: Ninguno.
- Valores predeterminados:
FastLength= 28SlowLength= 56CandleType= TimeSpan.FromMinutes(1)
- Filtros:
- Categoría: Tendencia
- Dirección: Ambos
- Indicadores: Highest, Lowest
- Stops: No
- Complejidad: Básico
- 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>
/// Strategy based on comparison of two ZigZag levels.
/// A short position is opened when the fast ZigZag level is above the slow one.
/// A long position is opened when the fast ZigZag level is below the slow one.
/// </summary>
public class RobotDanuStrategy : Strategy
{
private readonly StrategyParam<int> _fastLength;
private readonly StrategyParam<int> _slowLength;
private readonly StrategyParam<DataType> _candleType;
private decimal _lastFast;
private decimal _lastFastHigh;
private decimal _lastFastLow;
private int _fastDirection;
private decimal _lastSlow;
private decimal _lastSlowHigh;
private decimal _lastSlowLow;
private int _slowDirection;
/// <summary>
/// Fast ZigZag lookback length.
/// </summary>
public int FastLength
{
get => _fastLength.Value;
set => _fastLength.Value = value;
}
/// <summary>
/// Slow ZigZag lookback length.
/// </summary>
public int SlowLength
{
get => _slowLength.Value;
set => _slowLength.Value = value;
}
/// <summary>
/// The type of candles to use for strategy calculation.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance of the strategy.
/// </summary>
public RobotDanuStrategy()
{
_fastLength = Param(nameof(FastLength), 28)
.SetGreaterThanZero()
.SetDisplay("Fast ZigZag Length", "Lookback for fast ZigZag", "ZigZag")
.SetOptimize(5, 60, 5);
_slowLength = Param(nameof(SlowLength), 56)
.SetGreaterThanZero()
.SetDisplay("Slow ZigZag Length", "Lookback for slow ZigZag", "ZigZag")
.SetOptimize(20, 120, 10);
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).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();
_lastFast = 0m;
_lastFastHigh = 0m;
_lastFastLow = 0m;
_fastDirection = 0;
_lastSlow = 0m;
_lastSlowHigh = 0m;
_lastSlowLow = 0m;
_slowDirection = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fastHigh = new Highest { Length = FastLength };
var fastLow = new Lowest { Length = FastLength };
var slowHigh = new Highest { Length = SlowLength };
var slowLow = new Lowest { Length = SlowLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastHigh, fastLow, slowHigh, slowLow, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fastHigh, decimal fastLow, decimal slowHigh, decimal slowLow)
{
if (candle.State != CandleStates.Finished)
return;
// Update fast ZigZag pivot
if (candle.HighPrice >= fastHigh && _fastDirection != 1)
{
_lastFast = candle.HighPrice;
_lastFastHigh = candle.HighPrice;
_fastDirection = 1;
}
else if (candle.LowPrice <= fastLow && _fastDirection != -1)
{
_lastFast = candle.LowPrice;
_lastFastLow = candle.LowPrice;
_fastDirection = -1;
}
// Update slow ZigZag pivot
if (candle.HighPrice >= slowHigh && _slowDirection != 1)
{
_lastSlow = candle.HighPrice;
_lastSlowHigh = candle.HighPrice;
_slowDirection = 1;
}
else if (candle.LowPrice <= slowLow && _slowDirection != -1)
{
_lastSlow = candle.LowPrice;
_lastSlowLow = candle.LowPrice;
_slowDirection = -1;
}
// Trading logic: compare fast and slow pivots
if (_lastFast > _lastSlow && Position >= 0)
{ if (Position > 0) SellMarket(); SellMarket(); }
else if (_lastFast < _lastSlow && Position <= 0)
{ if (Position < 0) BuyMarket(); BuyMarket(); }
}
}
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 robot_danu_strategy(Strategy):
def __init__(self):
super(robot_danu_strategy, self).__init__()
self._fast_length = self.Param("FastLength", 28) \
.SetDisplay("Fast ZigZag Length", "Lookback for fast ZigZag", "ZigZag")
self._slow_length = self.Param("SlowLength", 56) \
.SetDisplay("Slow ZigZag Length", "Lookback for slow ZigZag", "ZigZag")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._last_fast = 0.0
self._last_fast_high = 0.0
self._last_fast_low = 0.0
self._fast_direction = 0
self._last_slow = 0.0
self._last_slow_high = 0.0
self._last_slow_low = 0.0
self._slow_direction = 0
@property
def fast_length(self):
return self._fast_length.Value
@property
def slow_length(self):
return self._slow_length.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(robot_danu_strategy, self).OnReseted()
self._last_fast = 0.0
self._last_fast_high = 0.0
self._last_fast_low = 0.0
self._fast_direction = 0
self._last_slow = 0.0
self._last_slow_high = 0.0
self._last_slow_low = 0.0
self._slow_direction = 0
def OnStarted2(self, time):
super(robot_danu_strategy, self).OnStarted2(time)
fast_high = Highest()
fast_high.Length = self.fast_length
fast_low = Lowest()
fast_low.Length = self.fast_length
slow_high = Highest()
slow_high.Length = self.slow_length
slow_low = Lowest()
slow_low.Length = self.slow_length
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast_high, fast_low, slow_high, slow_low, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def on_process(self, candle, fast_high, fast_low, slow_high, slow_low):
if candle.State != CandleStates.Finished:
return
# Update fast ZigZag pivot
if candle.HighPrice >= fast_high and self._fast_direction != 1:
self._last_fast = candle.HighPrice
self._last_fast_high = candle.HighPrice
self._fast_direction = 1
elif candle.LowPrice <= fast_low and self._fast_direction != -1:
self._last_fast = candle.LowPrice
self._last_fast_low = candle.LowPrice
self._fast_direction = -1
# Update slow ZigZag pivot
if candle.HighPrice >= slow_high and self._slow_direction != 1:
self._last_slow = candle.HighPrice
self._last_slow_high = candle.HighPrice
self._slow_direction = 1
elif candle.LowPrice <= slow_low and self._slow_direction != -1:
self._last_slow = candle.LowPrice
self._last_slow_low = candle.LowPrice
self._slow_direction = -1
# Trading logic: compare fast and slow pivots
if self._last_fast > self._last_slow and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
elif self._last_fast < self._last_slow and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
def CreateClone(self):
return robot_danu_strategy()