Plantilla de robot comercial AIS3
Descripción general
La plantilla del robot comercial AIS3 es un sistema de ruptura MetaTrader que se basa en dos marcos de tiempo coordinados. El plazo principal
captura la estructura de la vela anterior, mientras que un período de tiempo secundario mide la volatilidad reciente para controlar las actualizaciones finales.
Este puerto StockSharp reproduce fielmente el tamaño del pedido original, las comprobaciones de entrada y la lógica de seguimiento, pero se implementa en
parte superior de la estrategia de alto nivel API para que pueda ejecutarse dentro de Designer, Shell o cualquier host StockSharp personalizado.
Flujo de trabajo comercial
- Suscripciones a datos de mercado: la estrategia se suscribe a dos series de velas. La serie principal (predeterminada de 15 minutos) proporciona
el máximo, mínimo, cierre, punto medio y rango de la vela anterior. La serie secundaria (por defecto 1 minuto) mide el rango rápido utilizado
para paradas finales. Un feed del libro de pedidos en vivo mantiene los mejores precios de oferta y demanda actuales sincronizados con el MQL
MarketInfo original
solicitudes.
- Validación de rupturas:
- Una configuración larga se activa cuando el cierre anterior está por encima del punto medio y el precio de venta actual supera el anterior.
alto más el diferencial medido. El precio de entrada es el pedido actual.
- Una configuración corta requiere que el cierre anterior se mantenga por debajo del punto medio y que la oferta supere el mínimo anterior. el precio de entrada
es la oferta actual.
- Ambas direcciones heredan las comprobaciones de seguridad del corredor de la plantilla: la distancia entre la entrada y la parada/objetivo proyectado.
debe exceder el buffer de parada configurado, y la parada debe permanecer en el lado correcto del precio de entrada incluso después de sumar el
difundir.
- Órdenes de protección:
- La distancia de stop-loss es igual a
primaryRange × StopMultiplier y está anclada por encima (para largos) o por debajo (para cortos) del
vela de ruptura como se describe en el manual de integración.
- La distancia de obtención de beneficios es igual a
primaryRange × TakeMultiplier y se coloca desde el precio de entrada en la dirección comercial.
- Gestión comercial:
- Cuando una posición está abierta, el rango del período de tiempo secundario multiplicado por
TrailMultiplier define la distancia de seguimiento.
- El trailing stop solo se actualiza si la operación genera ganancias y el nuevo nivel está más lejos que la congelación y parada configuradas.
zonas de amortiguamiento y la distancia entre la parada actual y la propuesta supera
TrailStepMultiplier × spread. Esto refleja el
Requisito de plantilla de que el precio debe avanzar al menos un paso del recorrido antes de modificar la parada.
- Las posiciones se cierran con órdenes de mercado siempre que la oferta/demanda toque los niveles almacenados de stop-loss o take-profit.
Gestión del riesgo
- Reserva de cuenta:
AccountReserve mantiene bloqueada una fracción del capital de la cartera. La estrategia se niega a abrir nuevas posiciones
si el capital reservado fuera inferior al presupuesto del pedido solicitado. Esto coincide con el comportamiento de la plantilla donde el riesgo
La reserva protege la cuenta de pérdidas en cascada.
- Reserva de orden:
OrderReserve controla la parte del capital restante que se puede arriesgar por operación. El tamaño de la posición
se calcula como riskBudget / |entry - stop| y luego se alinea con el paso de volumen de seguridad. Si no hay métricas de cartera
disponible, en su lugar se utiliza el parámetro alternativo BaseVolume.
- Detener y congelar buffers:
StopBufferTicks y FreezeBufferTicks traducen las limitaciones de detención del corredor (por ejemplo, MODE_STOPLEVEL
y MODE_FREEZELEVEL de MetaTrader) en unidades de precio utilizando el paso del precio del valor. Impiden que la estrategia se emita
órdenes que violen las restricciones cambiarias o que muevan el trailing stop de manera demasiado agresiva.
- Multiplicador de pasos finales:
TrailStepMultiplier refleja la constante acd.TrailStepping de la plantilla MQ4. Asegura
que las actualizaciones finales solo ocurren cuando la nueva parada está al menos a un múltiplo del valor anterior.
Parámetros
| Parámetro |
Descripción |
AccountReserve |
Fracción del capital mantenido como reserva de seguridad (0–0,95). |
OrderReserve |
Fracción de capital negociable asignada al presupuesto de riesgo por operación (0–0,5 por defecto). |
PrimaryCandleType |
Plazo de trabajo para la detección de rupturas (velas predeterminadas de 15 minutos). |
SecondaryCandleType |
Marco de tiempo más rápido que controla la distancia de seguimiento (velas predeterminadas de 1 minuto). |
TakeMultiplier |
Multiplicador del rango principal utilizado para realizar la orden de toma de ganancias. |
StopMultiplier |
Multiplicador del rango primario utilizado para calcular la parada de protección. |
TrailMultiplier |
Multiplicador del rango secundario que define la distancia de seguimiento. |
BaseVolume |
Tamaño de la posición alternativa cuando las métricas de la cartera no están disponibles. |
StopBufferTicks |
Distancia adicional, en ticks de precio, que debe permanecer entre los niveles de entrada y stop/objetivo. |
FreezeBufferTicks |
Búfer adicional que evita detener las actualizaciones demasiado cerca del nivel de congelación del broker. |
TrailStepMultiplier |
Multiplicador de diferencial que define el incremento mínimo entre los ajustes finales. |
Notas de uso
- Alimente la estrategia con series de velas y un flujo de libro de órdenes o de nivel 1 para que los mejores precios de oferta y demanda estén disponibles. corriendo
basarse únicamente en los datos de la última operación alterará los controles de ruptura porque dependen del diferencial.
- Los valores de parámetros predeterminados replican el ejemplo de plantilla MQ4 (
TakeMultiplier = 1, StopMultiplier = 2,
TrailMultiplier = 3). Ajústelos para que coincidan con los activos con los que opera o para experimentar con la intensidad de la ruptura.
- El trailing stop es virtual: las órdenes no se modifican en la bolsa. Cuando se cumple la condición de seguimiento, la estrategia simplemente
emite una salida de mercado, reflejando cómo el asesor experto original gestionó las paradas internamente.
- Combine la estrategia con el módulo de protección integrado de StockSharp (ya habilitado en el constructor) para mantener la emergencia.
manejo de stop-loss incluso si la estrategia se desconecta temporalmente.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// AIS3 Trading Robot: breakout strategy with ATR-based stops and trailing.
/// Enters on breakout above/below previous candle range with EMA filter.
/// </summary>
public class Ais3TradingRobotTemplateStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _atrLength;
private readonly StrategyParam<decimal> _takeMultiplier;
private readonly StrategyParam<decimal> _stopMultiplier;
private decimal _prevHigh;
private decimal _prevLow;
private decimal _entryPrice;
private decimal _stopPrice;
public Ais3TradingRobotTemplateStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Timeframe.", "General");
_emaLength = Param(nameof(EmaLength), 20)
.SetDisplay("EMA Length", "EMA period for trend filter.", "Indicators");
_atrLength = Param(nameof(AtrLength), 14)
.SetDisplay("ATR Length", "ATR period.", "Indicators");
_takeMultiplier = Param(nameof(TakeMultiplier), 2.0m)
.SetDisplay("Take Multiplier", "ATR multiplier for TP.", "Risk");
_stopMultiplier = Param(nameof(StopMultiplier), 1.5m)
.SetDisplay("Stop Multiplier", "ATR multiplier for SL.", "Risk");
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int EmaLength
{
get => _emaLength.Value;
set => _emaLength.Value = value;
}
public int AtrLength
{
get => _atrLength.Value;
set => _atrLength.Value = value;
}
public decimal TakeMultiplier
{
get => _takeMultiplier.Value;
set => _takeMultiplier.Value = value;
}
public decimal StopMultiplier
{
get => _stopMultiplier.Value;
set => _stopMultiplier.Value = value;
}
/// <inheritdoc />
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevHigh = 0;
_prevLow = 0;
_entryPrice = 0;
_stopPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevHigh = 0;
_prevLow = 0;
_entryPrice = 0;
_stopPrice = 0;
var ema = new ExponentialMovingAverage { Length = EmaLength };
var atr = new AverageTrueRange { Length = AtrLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, atr, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal, decimal atrVal)
{
if (candle.State != CandleStates.Finished)
return;
if (_prevHigh == 0 || atrVal <= 0)
{
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
return;
}
var close = candle.ClosePrice;
var takeDistance = atrVal * TakeMultiplier;
var stopDistance = atrVal * StopMultiplier;
// Manage position
if (Position > 0)
{
if (close - _entryPrice >= takeDistance)
{
SellMarket();
_entryPrice = 0;
_stopPrice = 0;
}
else if (_stopPrice > 0 && close <= _stopPrice)
{
SellMarket();
_entryPrice = 0;
_stopPrice = 0;
}
else
{
var trail = close - stopDistance;
if (trail > _stopPrice) _stopPrice = trail;
}
}
else if (Position < 0)
{
if (_entryPrice - close >= takeDistance)
{
BuyMarket();
_entryPrice = 0;
_stopPrice = 0;
}
else if (_stopPrice > 0 && close >= _stopPrice)
{
BuyMarket();
_entryPrice = 0;
_stopPrice = 0;
}
else
{
var trail = close + stopDistance;
if (trail < _stopPrice || _stopPrice == 0) _stopPrice = trail;
}
}
// Entry on breakout + EMA filter
if (Position == 0)
{
if (close > _prevHigh && close > emaVal)
{
_entryPrice = close;
_stopPrice = close - stopDistance;
BuyMarket();
}
else if (close < _prevLow && close < emaVal)
{
_entryPrice = close;
_stopPrice = close + stopDistance;
SellMarket();
}
}
_prevHigh = candle.HighPrice;
_prevLow = candle.LowPrice;
}
}
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, AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class ais3_trading_robot_template_strategy(Strategy):
"""
AIS3 Trading Robot: breakout strategy with ATR-based stops and trailing.
Enters on breakout above/below previous candle range with EMA filter.
"""
def __init__(self):
super(ais3_trading_robot_template_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Timeframe.", "General")
self._ema_length = self.Param("EmaLength", 20) \
.SetDisplay("EMA Length", "EMA period for trend filter.", "Indicators")
self._atr_length = self.Param("AtrLength", 14) \
.SetDisplay("ATR Length", "ATR period.", "Indicators")
self._take_multiplier = self.Param("TakeMultiplier", 2.0) \
.SetDisplay("Take Multiplier", "ATR multiplier for TP.", "Risk")
self._stop_multiplier = self.Param("StopMultiplier", 1.5) \
.SetDisplay("Stop Multiplier", "ATR multiplier for SL.", "Risk")
self._prev_high = 0.0
self._prev_low = 0.0
self._entry_price = 0.0
self._stop_price = 0.0
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def EmaLength(self):
return self._ema_length.Value
@EmaLength.setter
def EmaLength(self, value):
self._ema_length.Value = value
@property
def AtrLength(self):
return self._atr_length.Value
@AtrLength.setter
def AtrLength(self, value):
self._atr_length.Value = value
@property
def TakeMultiplier(self):
return self._take_multiplier.Value
@TakeMultiplier.setter
def TakeMultiplier(self, value):
self._take_multiplier.Value = value
@property
def StopMultiplier(self):
return self._stop_multiplier.Value
@StopMultiplier.setter
def StopMultiplier(self, value):
self._stop_multiplier.Value = value
def OnReseted(self):
super(ais3_trading_robot_template_strategy, self).OnReseted()
self._prev_high = 0.0
self._prev_low = 0.0
self._entry_price = 0.0
self._stop_price = 0.0
def OnStarted2(self, time):
super(ais3_trading_robot_template_strategy, self).OnStarted2(time)
self._prev_high = 0.0
self._prev_low = 0.0
self._entry_price = 0.0
self._stop_price = 0.0
ema = ExponentialMovingAverage()
ema.Length = self.EmaLength
atr = AverageTrueRange()
atr.Length = self.AtrLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, atr, self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def ProcessCandle(self, candle, ema_val, atr_val):
if candle.State != CandleStates.Finished:
return
if self._prev_high == 0 or atr_val <= 0:
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
return
close = float(candle.ClosePrice)
take_distance = atr_val * self.TakeMultiplier
stop_distance = atr_val * self.StopMultiplier
# Manage position
if self.Position > 0:
if close - self._entry_price >= take_distance:
self.SellMarket()
self._entry_price = 0.0
self._stop_price = 0.0
elif self._stop_price > 0 and close <= self._stop_price:
self.SellMarket()
self._entry_price = 0.0
self._stop_price = 0.0
else:
trail = close - stop_distance
if trail > self._stop_price:
self._stop_price = trail
elif self.Position < 0:
if self._entry_price - close >= take_distance:
self.BuyMarket()
self._entry_price = 0.0
self._stop_price = 0.0
elif self._stop_price > 0 and close >= self._stop_price:
self.BuyMarket()
self._entry_price = 0.0
self._stop_price = 0.0
else:
trail = close + stop_distance
if trail < self._stop_price or self._stop_price == 0:
self._stop_price = trail
# Entry on breakout + EMA filter
if self.Position == 0:
if close > self._prev_high and close > ema_val:
self._entry_price = close
self._stop_price = close - stop_distance
self.BuyMarket()
elif close < self._prev_low and close < ema_val:
self._entry_price = close
self._stop_price = close + stop_distance
self.SellMarket()
self._prev_high = float(candle.HighPrice)
self._prev_low = float(candle.LowPrice)
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return ais3_trading_robot_template_strategy()