La estrategia Breadandbutter2 es una conversión directa del asesor experto MT4 de MQL/7710/Breadandbutter2.mq4. El sistema monitorea velas de una hora y rastrea tres promedios móviles ponderados lineales (LWMA) basados en los precios de apertura de las velas. Un cruce sincronizado de los tres promedios indica un cambio de tendencia. La estrategia invierte inmediatamente la posición para alinearla con la nueva dirección y, opcionalmente, piramidalmente órdenes adicionales mientras persiste la tendencia.
Lógica principal
Suscríbase a velas de una hora (configurables a través de Tipo de vela).
Calcule LWMA(5), LWMA(10) y LWMA(15) en las aperturas de velas.
Detectar una reversión alcista cuando la vela anterior tenía LWMA5 < LWMA10 < LWMA15 y la vela actual muestra LWMA5 > LWMA10 > LWMA15. Detectar una reversión bajista con la secuencia de desigualdad opuesta.
En un cruce alcista, apunte a una posición larga de lotes de Volumen. En un cruce bajista, apunte a una posición corta del mismo tamaño. La estrategia ajusta la posición existente comprando o vendiendo sólo la diferencia entre la exposición actual y la objetivo.
Después de cada entrada, el contador Intervalo se reinicia. Una vez que las velas terminadas del Intervalo pasan sin un nuevo cruce, la estrategia agrega otra orden en la dirección actual (piramidal) y actualiza las órdenes de protección.
El objetivo de ganancias y el límite de pérdidas se adjuntan a cada posición resultante utilizando distancias Take Profit y Stop Loss expresadas en pasos de precio. Establecer cualquiera de los valores en cero desactiva la protección correspondiente.
Parámetros
Nombre
Predeterminado
Descripción
Volumen
0.1
Tamaño del pedido en lotes para cada entrada base y capa piramidal.
Obtener ganancias
20
Distancia en pasos de precio para la orden de toma de ganancias. Establezca en 0 para desactivar.
Detener pérdidas
20
Distancia en pasos de precio para el tope de protección. Establezca en 0 para desactivar.
Intervalo
4
Número de velas terminadas que se deben esperar antes de agregar otra posición de pirámide. Zero desactiva la piramidización.
Filtro cruzado
1.1
Parámetro reservado conservado del código original para futuros filtrados ADX (actualmente no utilizado).
Tipo de vela
plazo de 1 hora
Fuente de datos de velas para los cálculos de LWMA.
Gestión de Puestos
El método auxiliar AdjustPosition garantiza que la posición final coincida exactamente con la exposición deseada después de cada cruce.
Las operaciones piramidales se basan en el signo actual de Position para agregar lotes únicamente en la dirección existente.
SetTakeProfit y SetStopLoss se invocan después de cada operación para mantener los controles de riesgo sincronizados con el último tamaño de la posición.
Notas
El script MT4 calculó un valor ADX pero nunca lo usó; el parámetro Filtro cruzado se conserva por motivos de compatibilidad y extensión futura.
La implementación original MQL tenía el contador de intervalo comentado. La versión StockSharp activa el comportamiento piramidal previsto al contar las velas terminadas.
Se llama a StartProtection() durante OnStarted para activar los servicios de protección de posición integrados.
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>
/// Bread and Butter strategy - triple WMA crossover.
/// Buys when WMA(5) crosses above WMA(10) and WMA(10) is above WMA(15).
/// Sells when WMA(5) crosses below WMA(10) and WMA(10) is below WMA(15).
/// </summary>
public class Breadandbutter2Strategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private decimal _prevWma5;
private decimal _prevWma10;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Breadandbutter2Strategy()
{
_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(); _prevWma5 = 0m; _prevWma10 = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var wma5 = new WeightedMovingAverage { Length = 5 };
var wma10 = new WeightedMovingAverage { Length = 10 };
var wma15 = new WeightedMovingAverage { Length = 15 };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(wma5, wma10, wma15, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal wma5, decimal wma10, decimal wma15)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevWma5 = wma5;
_prevWma10 = wma10;
_hasPrev = true;
return;
}
if (_prevWma5 <= _prevWma10 && wma5 > wma10 && wma10 > wma15 && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
else if (_prevWma5 >= _prevWma10 && wma5 < wma10 && wma10 < wma15 && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevWma5 = wma5;
_prevWma10 = wma10;
}
}