Conversión del asesor experto MetaTrader 4 alliheik.mq4. La estrategia combina un cuerpo de vela Heiken Ashi con doble suavizado con la media móvil de "mandíbula" Alligator desplazada hacia adelante. Las entradas se producen cuando los buffers de Heiken Ashi se cruzan después del proceso de suavizado. Las salidas se basan en un filtro cruzado de mandíbula, objetivos fijos opcionales y un trailing stop basado en el precio.
Lógica de trading
Construcción Heiken Ashi
Suaviza los precios de apertura, máximo, mínimo y cierre sin procesar con PreSmoothMethod / PreSmoothPeriod.
Construya velas Heiken Ashi clásicas a partir de precios suavizados.
Intercambie los buffers alto/bajo dependiendo del color de la vela (alcista mantiene orden bajo/alto, bajista los invierte).
Aplique una segunda pasada de suavizado (PostSmoothMethod / PostSmoothPeriod) a los buffers condicionales. Estos son los valores comparados en las reglas de señales.
Definición de señal
Largo: el búfer inferior actual está debajo del búfer superior, mientras que la barra anterior tenía la relación opuesta o igual.
Corto: el búfer inferior actual está por encima del búfer superior mientras que la barra anterior tenía la relación opuesta o igual.
Filtro de mandíbula y arrastre
La mandíbula Alligator es una media móvil de JawsPeriod barras, desplazadas JawsShift barras hacia adelante y alimentadas con JawsPrice.
Close[6] (hace seis compases) debe cruzar la mandíbula antes de que la posición pueda cerrarse automáticamente.
Una vez que la diferencia entre Close[6] y la mandíbula alcanza los ocho puntos y se invierte a través de la mandíbula, la posición se cierra.
Si TrailingStopPoints es mayor que cero, el precio de parada sigue a Close[6] una vez que la vela esté en el lado rentable de la mandíbula.
Paradas y objetivos
StopLossPoints y TakeProfitPoints son distancias fijas opcionales que se aplican al ingresar.
La lógica de seguimiento sobrescribe la parada protectora una vez que se mueve a favor de la operación.
Parámetros predeterminados
Parámetro
Predeterminado
Descripción
CandleType
TimeSpan.FromHours(1).TimeFrame()
Marco de tiempo utilizado para todos los cálculos.
JawsPeriod
144
Longitud del promedio móvil de la mandíbula Alligator.
JawsShift
8
Desplazamiento hacia adelante de la mandíbula (número de barras).
JawsMethod
Sencillo
Tipo de media móvil para la mandíbula (simple, exponencial, suavizada, ponderada).
JawsPrice
Cerrar
Componente de precio suministrado a la mandíbula (Cerrar/Abrir/Alto/Bajo/Mediano/Típico/Ponderado).
PreSmoothMethod
exponencial
Promedio móvil utilizado para suavizar los valores OHLC sin procesar antes de calcular Heiken Ashi.
PreSmoothPeriod
21
Periodo de los promedios previos al suavizado.
PostSmoothMethod
ponderado
Media móvil aplicada a los buffers condicionales de Heiken Ashi.
PostSmoothPeriod
1
Periodo de los promedios post-alisamiento (1 mantiene los buffers originales).
StopLossPoints
0
Distancia de parada fija en puntos (0 inhabilitaciones).
TrailingStopPoints
0
Distancia de trailing stop basada en Close[6] (0 inhabilitaciones).
TakeProfitPoints
225
Distancia de toma de ganancias en puntos (0 inhabilitaciones).
OrderVolume
0.1
Tamaño del lote para entradas.
Indicadores utilizados
MA de pre-suavizado (cuatro series paralelas para apertura, máximo, mínimo y cierre).
Reconstrucción de Heiken Ashi impulsada por la suavización de precios.
MA post-suavizado de los buffers condicionales que forman la señal de entrada.
Alligator promedio de movimiento de mandíbula con tipo, desplazamiento y precio aplicado ajustables.
Resumen de entrada y salida
Ingrese Largo cuando el buffer inferior suavizado cruza por debajo del buffer superior y la barra anterior no era alcista (condición de cruce descrita anteriormente).
Salida larga cuando:
Close[6] vuelve a caer por debajo de la mandíbula después de haber estado previamente por encima de ella y la distancia alcanzó ≥ 8 puntos; o
Se alcanza el objetivo TakeProfitPoints; o
Se alcanza la parada StopLossPoints/TrailingStopPoints.
Ingrese Corto cuando el buffer inferior suavizado cruce por encima del buffer superior y la barra anterior no era bajista.
Salida corta cuando:
Close[6] vuelve a subir por encima de la mandíbula después de haber estado previamente por debajo de ella y la distancia alcanzada ≥ 8 puntos; o
Se alcanza el objetivo TakeProfitPoints; o
Se alcanza la parada StopLossPoints/TrailingStopPoints.
Notas de conversión
La estrategia aplica una operación por barra, reflejando la verificación isOrderAllowed() en el EA original.
Los objetivos y paradas de protección se simulan internamente porque las estrategias StockSharp no pueden depender de las órdenes MT4 del corredor.
El promedio móvil de la mandíbula almacena valores históricos para que el desplazamiento hacia adelante replique el comportamiento de iMA con ma_shift = JawsShift.
Todos los cálculos utilizan aritmética decimal y vinculaciones de indicadores consistentes con los requisitos API de alto nivel de StockSharp.
Riesgo y uso
Diseñado para operaciones largas y cortas con el mismo instrumento.
Funciona mejor en mercados de tendencia donde el cambio de mandíbula y el suavizado Heiken Ashi pueden resaltar cambios a mediano plazo.
Considere ajustar TrailingStopPoints y TakeProfitPoints para que coincidan con la volatilidad del instrumento.
Siempre realice pruebas retrospectivas y directas en cuentas en papel antes de la implementación real.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Alliheik Trader: uses smoothed Heiken Ashi candles (EMA of OHLC)
/// with Alligator jaw (long SMA) as trend filter.
/// Entry on HA color change above/below jaw, exit on reversal.
/// </summary>
public class AlliheikTraderStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _smoothPeriod;
private readonly StrategyParam<int> _jawPeriod;
private decimal _prevHaOpen;
private decimal _prevHaClose;
private bool _prevBullish;
private bool _hasPrev;
private decimal _entryPrice;
public AlliheikTraderStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Timeframe.", "General");
_smoothPeriod = Param(nameof(SmoothPeriod), 6)
.SetDisplay("Smooth Period", "EMA period for HA smoothing.", "Indicators");
_jawPeriod = Param(nameof(JawPeriod), 144)
.SetDisplay("Jaw Period", "SMA period for Alligator jaw.", "Indicators");
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int SmoothPeriod
{
get => _smoothPeriod.Value;
set => _smoothPeriod.Value = value;
}
public int JawPeriod
{
get => _jawPeriod.Value;
set => _jawPeriod.Value = value;
}
/// <inheritdoc />
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevHaOpen = 0;
_prevHaClose = 0;
_prevBullish = false;
_hasPrev = false;
_entryPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevHaOpen = 0;
_prevHaClose = 0;
_prevBullish = false;
_hasPrev = false;
_entryPrice = 0;
var ema = new ExponentialMovingAverage { Length = SmoothPeriod };
var jaw = new SimpleMovingAverage { Length = JawPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, jaw, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, jaw);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal, decimal jawVal)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
// Compute smoothed Heiken Ashi
var haClose = (candle.OpenPrice + candle.HighPrice + candle.LowPrice + close) / 4m;
var haOpen = _prevHaOpen == 0
? (candle.OpenPrice + close) / 2m
: (_prevHaOpen + _prevHaClose) / 2m;
var bullish = haClose > haOpen;
if (!_hasPrev)
{
_prevHaOpen = haOpen;
_prevHaClose = haClose;
_prevBullish = bullish;
_hasPrev = true;
return;
}
var colorChange = bullish != _prevBullish;
// Exit on color change
if (Position > 0 && colorChange && !bullish)
{
SellMarket();
_entryPrice = 0;
}
else if (Position < 0 && colorChange && bullish)
{
BuyMarket();
_entryPrice = 0;
}
// Entry on color change confirmed by jaw filter
if (Position == 0 && colorChange)
{
if (bullish && close > jawVal)
{
_entryPrice = close;
BuyMarket();
}
else if (!bullish && close < jawVal)
{
_entryPrice = close;
SellMarket();
}
}
_prevHaOpen = haOpen;
_prevHaClose = haClose;
_prevBullish = bullish;
}
}
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 ExponentialMovingAverage, SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class alliheik_trader_strategy(Strategy):
"""
Alliheik Trader: uses smoothed Heiken Ashi candles (EMA of OHLC)
with Alligator jaw (long SMA) as trend filter.
Entry on HA color change above/below jaw, exit on reversal.
"""
def __init__(self):
super(alliheik_trader_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Timeframe.", "General")
self._smooth_period = self.Param("SmoothPeriod", 6) \
.SetDisplay("Smooth Period", "EMA period for HA smoothing.", "Indicators")
self._jaw_period = self.Param("JawPeriod", 144) \
.SetDisplay("Jaw Period", "SMA period for Alligator jaw.", "Indicators")
self._prev_ha_open = 0.0
self._prev_ha_close = 0.0
self._prev_bullish = False
self._has_prev = False
self._entry_price = 0.0
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, v): self._candle_type.Value = v
@property
def SmoothPeriod(self): return self._smooth_period.Value
@SmoothPeriod.setter
def SmoothPeriod(self, v): self._smooth_period.Value = v
@property
def JawPeriod(self): return self._jaw_period.Value
@JawPeriod.setter
def JawPeriod(self, v): self._jaw_period.Value = v
def OnReseted(self):
super(alliheik_trader_strategy, self).OnReseted()
self._prev_ha_open = 0.0
self._prev_ha_close = 0.0
self._prev_bullish = False
self._has_prev = False
self._entry_price = 0.0
def OnStarted2(self, time):
super(alliheik_trader_strategy, self).OnStarted2(time)
self._prev_ha_open = 0.0
self._prev_ha_close = 0.0
self._prev_bullish = False
self._has_prev = False
self._entry_price = 0.0
ema = ExponentialMovingAverage()
ema.Length = self.SmoothPeriod
jaw = SimpleMovingAverage()
jaw.Length = self.JawPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, jaw, self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, jaw)
self.DrawOwnTrades(area)
def ProcessCandle(self, candle, ema_val, jaw_val):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
o = float(candle.OpenPrice)
h = float(candle.HighPrice)
l = float(candle.LowPrice)
# Compute smoothed Heiken Ashi
ha_close = (o + h + l + close) / 4.0
if self._prev_ha_open == 0:
ha_open = (o + close) / 2.0
else:
ha_open = (self._prev_ha_open + self._prev_ha_close) / 2.0
bullish = ha_close > ha_open
if not self._has_prev:
self._prev_ha_open = ha_open
self._prev_ha_close = ha_close
self._prev_bullish = bullish
self._has_prev = True
return
color_change = bullish != self._prev_bullish
# Exit on color change
if self.Position > 0 and color_change and not bullish:
self.SellMarket()
self._entry_price = 0.0
elif self.Position < 0 and color_change and bullish:
self.BuyMarket()
self._entry_price = 0.0
# Entry on color change confirmed by jaw filter
if self.Position == 0 and color_change:
if bullish and close > jaw_val:
self._entry_price = close
self.BuyMarket()
elif not bullish and close < jaw_val:
self._entry_price = close
self.SellMarket()
self._prev_ha_open = ha_open
self._prev_ha_close = ha_close
self._prev_bullish = bullish
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return alliheik_trader_strategy()