A estratégia Breadandbutter2 é uma conversão direta do consultor especialista MT4 de MQL/7710/Breadandbutter2.mq4. O sistema monitora velas de uma hora e rastreia três médias móveis lineares ponderadas (LWMA) construídas sobre os preços de abertura das velas. Um cruzamento sincronizado das três médias indica uma reversão de tendência. A estratégia imediatamente inverte a posição para se alinhar com a nova direção e, opcionalmente, coloca pedidos adicionais em pirâmide enquanto a tendência persiste.
Lógica principal
Assine velas de uma hora (configuráveis via Tipo de vela).
Calcule LWMA(5), LWMA(10) e LWMA(15) na abertura da vela.
Detecte uma reversão de alta quando a vela anterior tinha LWMA5 < LWMA10 < LWMA15 e a vela atual mostra LWMA5 > LWMA10 > LWMA15. Detecte uma reversão de baixa com a sequência de desigualdade oposta.
Em um cruzamento de alta, vise uma posição longa de lotes de Volume. Em um cruzamento de baixa, vise uma posição curta de tamanho igual. A estratégia ajusta a posição existente comprando ou vendendo apenas a diferença entre a exposição atual e a exposição alvo.
Após cada entrada, o contador de Intervalo é reiniciado. Depois que as velas finalizadas do Intervalo passam sem um novo cruzamento, a estratégia adiciona outra ordem na direção atual (pirâmide) e atualiza as ordens de proteção.
A meta de lucro e o limite de perda são anexados a cada posição resultante usando distâncias Take Profit e Stop Loss expressas em etapas de preço. Definir qualquer um dos valores como zero desativa a proteção correspondente.
Parâmetros
Nome
Padrão
Descrição
Volume
0,1
Tamanho do pedido em lotes para cada entrada base e camada da pirâmide.
Receba lucro
20
Distância nas etapas de preço para a ordem de realização de lucro. Defina como 0 para desativar.
Stop Loss
20
Distância em etapas de preço para o stop protetor. Defina como 0 para desativar.
Intervalo
4
Número de velas finalizadas que devem ser aguardadas antes de adicionar outra posição na pirâmide. Zero desativa a pirâmide.
Filtro Cruzado
1.1
Parâmetro reservado mantido no código original para filtragem ADX futura (atualmente não usado).
Tipo de vela
Período de 1 hora
Fonte de dados Candle para os cálculos LWMA.
Gerenciamento de posição
O método auxiliar AdjustPosition garante que a posição final corresponda exatamente à exposição desejada após cada cruzamento.
As negociações em pirâmide dependem do sinal atual de Position para adicionar lotes apenas na direção existente.
SetTakeProfit e SetStopLoss são invocados após cada negociação para manter os controles de risco sincronizados com o tamanho da posição mais recente.
Notas
O script MT4 calculou um valor ADX mas nunca o utilizou; o parâmetro Cross Filter é mantido para compatibilidade e extensão futura.
A implementação original do MQL teve o contador de intervalo comentado. A versão StockSharp ativa o comportamento de pirâmide pretendido contando velas concluídas.
StartProtection() é chamado durante OnStarted para ativar serviços integrados de proteção de posição.
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;
}
}