Estrategia Alligator + MA Trend Catcher
Esta estrategia combina el Alligator de Bill Williams con una EMA de 200 períodos como filtro de tendencia. Se abre una posición larga cuando el precio está por encima de la línea de tendencia y las líneas del Alligator (labios, dientes, mandíbula) están alineadas hacia arriba. Se abre una posición corta cuando el precio está por debajo de la línea de tendencia y las líneas del Alligator están alineadas hacia abajo. Las posiciones se cierran cuando ocurre la alineación contraria.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Alligator + MA Trend Catcher strategy.
/// Buy when price is above the EMA trendline and Alligator lines are aligned up.
/// Sell short when price is below the trendline and Alligator lines are aligned down.
/// </summary>
public class AlligatorMaTrendCatcherStrategy : Strategy
{
private readonly StrategyParam<int> _jawLength;
private readonly StrategyParam<int> _teethLength;
private readonly StrategyParam<int> _lipsLength;
private readonly StrategyParam<int> _trendlineLength;
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cooldownBars;
private int _cooldownRemaining;
public int JawLength { get => _jawLength.Value; set => _jawLength.Value = value; }
public int TeethLength { get => _teethLength.Value; set => _teethLength.Value = value; }
public int LipsLength { get => _lipsLength.Value; set => _lipsLength.Value = value; }
public int TrendlineLength { get => _trendlineLength.Value; set => _trendlineLength.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int CooldownBars { get => _cooldownBars.Value; set => _cooldownBars.Value = value; }
public AlligatorMaTrendCatcherStrategy()
{
_jawLength = Param(nameof(JawLength), 13)
.SetGreaterThanZero()
.SetDisplay("Jaw Length", "Length of jaw SMA", "Alligator");
_teethLength = Param(nameof(TeethLength), 8)
.SetGreaterThanZero()
.SetDisplay("Teeth Length", "Length of teeth SMA", "Alligator");
_lipsLength = Param(nameof(LipsLength), 5)
.SetGreaterThanZero()
.SetDisplay("Lips Length", "Length of lips SMA", "Alligator");
_trendlineLength = Param(nameof(TrendlineLength), 50)
.SetGreaterThanZero()
.SetDisplay("EMA Length", "Length of the EMA trendline", "Trendline");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
_cooldownBars = Param(nameof(CooldownBars), 30)
.SetDisplay("Cooldown Bars", "Bars between trades", "Risk");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_cooldownRemaining = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var jaw = new SmoothedMovingAverage { Length = JawLength };
var teeth = new SmoothedMovingAverage { Length = TeethLength };
var lips = new SmoothedMovingAverage { Length = LipsLength };
var trend = new ExponentialMovingAverage { Length = TrendlineLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(jaw, teeth, lips, trend, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, trend);
DrawIndicator(area, jaw);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal jawMa, decimal teethMa, decimal lipsMa, decimal trendline)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (_cooldownRemaining > 0)
{
_cooldownRemaining--;
return;
}
var alligatorUp = lipsMa > teethMa && teethMa > jawMa;
var alligatorDown = lipsMa < teethMa && teethMa < jawMa;
if (alligatorUp && candle.ClosePrice > trendline && Position <= 0)
{
if (Position < 0)
BuyMarket(Math.Abs(Position));
BuyMarket(Volume);
_cooldownRemaining = CooldownBars;
}
else if (alligatorDown && candle.ClosePrice < trendline && Position >= 0)
{
if (Position > 0)
SellMarket(Math.Abs(Position));
SellMarket(Volume);
_cooldownRemaining = CooldownBars;
}
}
}
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 SmoothedMovingAverage, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class alligator_ma_trend_catcher_strategy(Strategy):
def __init__(self):
super(alligator_ma_trend_catcher_strategy, self).__init__()
self._jaw_length = self.Param("JawLength", 13) \
.SetGreaterThanZero() \
.SetDisplay("Jaw Length", "Length of jaw SMA", "Alligator")
self._teeth_length = self.Param("TeethLength", 8) \
.SetGreaterThanZero() \
.SetDisplay("Teeth Length", "Length of teeth SMA", "Alligator")
self._lips_length = self.Param("LipsLength", 5) \
.SetGreaterThanZero() \
.SetDisplay("Lips Length", "Length of lips SMA", "Alligator")
self._trendline_length = self.Param("TrendlineLength", 50) \
.SetGreaterThanZero() \
.SetDisplay("EMA Length", "Length of the EMA trendline", "Trendline")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._cooldown_bars = self.Param("CooldownBars", 30) \
.SetDisplay("Cooldown Bars", "Bars between trades", "Risk")
self._cooldown_remaining = 0
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
@property
def cooldown_bars(self):
return self._cooldown_bars.Value
@cooldown_bars.setter
def cooldown_bars(self, value):
self._cooldown_bars.Value = value
def OnReseted(self):
super(alligator_ma_trend_catcher_strategy, self).OnReseted()
self._cooldown_remaining = 0
def OnStarted2(self, time):
super(alligator_ma_trend_catcher_strategy, self).OnStarted2(time)
jaw = SmoothedMovingAverage()
jaw.Length = self._jaw_length.Value
teeth = SmoothedMovingAverage()
teeth.Length = self._teeth_length.Value
lips = SmoothedMovingAverage()
lips.Length = self._lips_length.Value
trend = ExponentialMovingAverage()
trend.Length = self._trendline_length.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(jaw, teeth, lips, trend, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, trend)
self.DrawIndicator(area, jaw)
self.DrawOwnTrades(area)
def OnProcess(self, candle, jaw_val, teeth_val, lips_val, trend_val):
if candle.State != CandleStates.Finished:
return
if self._cooldown_remaining > 0:
self._cooldown_remaining -= 1
return
jaw_v = float(jaw_val)
teeth_v = float(teeth_val)
lips_v = float(lips_val)
trendline = float(trend_val)
close = float(candle.ClosePrice)
alligator_up = lips_v > teeth_v and teeth_v > jaw_v
alligator_down = lips_v < teeth_v and teeth_v < jaw_v
if alligator_up and close > trendline and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
self._cooldown_remaining = self.cooldown_bars
elif alligator_down and close < trendline and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._cooldown_remaining = self.cooldown_bars
def CreateClone(self):
return alligator_ma_trend_catcher_strategy()