Esta estratégia replica a ideia original do MetaTrader "Modelo Martingale simples" em StockSharp. Ele analisa velas concluídas de um período configurável usando um par de médias móveis simples (SMA). Um filtro de rompimento verifica se o fechamento da vela anterior rompe a máxima ou a mínima de uma vela ainda anterior para confirmar a direção. O tamanho da posição segue uma sequência de martingale: após cada ciclo perdedor, o próximo volume de negociação é multiplicado, enquanto os ciclos lucrativos redefinem o volume para o tamanho base configurado.
Lógica de negociação
Assine velas do período CandleType. Apenas velas finalizadas participam da geração do sinal.
Calcule um SMA rápido e um SMA lento no fechamento da vela.
Gere um sinal de compra quando:
o último fechamento da vela concluído está acima do rápido SMA,
o rápido SMA está acima do lento SMA,
na vela anterior, o rápido SMA estava abaixo do lento SMA, e
o último fechamento da vela concluído está acima da máxima da vela há duas barras.
Gere um sinal de venda quando as condições simétricas ocorrerem no lado negativo, incluindo o fechamento abaixo da mínima da vela há duas barras.
Quando um sinal disparar e não houver posições abertas ou ordens ativas, envie uma ordem de mercado usando o volume de martingale atualmente calculado.
Anexe níveis sintéticos de stop-loss e take-profit monitorando velas futuras. Quando o preço atingir qualquer nível, feche a posição aberta.
Após o fechamento de uma posição e a atualização do saldo da carteira:
se o saldo aumentar, redefina o volume para o valor BaseVolume;
se o saldo diminuiu, multiplique o último volume de negociação por Multiplier e alinhe-o com a etapa de volume do instrumento.
Parâmetros
Nome
Descrição
StopLossPoints
Distância da entrada até a parada de proteção nas faixas de preço.
TakeProfitPoints
Distância da entrada até a meta de lucro em faixas de preço.
BaseVolume
Tamanho inicial do lote para o ciclo martingale.
Multiplier
Fator aplicado ao tamanho do lote anterior após perda.
FastPeriod
Comprimento do SMA rápido usado para polarização direcional.
SlowPeriod
Comprimento da lentidão SMA para confirmação de tendência.
CandleType
Prazo de velas processadas pela estratégia.
Gestão de capital
A escada martingale reage estritamente às mudanças de equilíbrio realizadas. Pequenas flutuações (±0,01 unidades monetárias) são ignoradas para evitar ruído.
Os volumes são alinhados ao instrumento VolumeStep, MinVolume e MaxVolume para garantir tamanhos de pedido válidos.
Os níveis de stop-loss e take-profit são monitorados nos extremos das velas (alta/baixa) em vez de colocar ordens de câmbio, refletindo a implementação original do MQL que usava saídas de mercado.
Notas de uso
Escolha um período de tempo e uma combinação de símbolos que produza velas históricas suficientes para que ambos os SMAs se formem antes de permitir a negociação.
Ajuste StopLossPoints e TakeProfitPoints para corresponder ao tamanho do tick do símbolo; eles representam contagens de pontos, não unidades de preço.
Considere testar diferentes multiplicadores e volumes básicos para controlar os requisitos de capital porque as sequências de martingale crescem rapidamente.
A estratégia chama StartProtection() no início para integração com os recursos padrão de gerenciamento de risco de StockSharp.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Simple Martingale Template strategy: SMA crossover with momentum confirmation.
/// Buys on fast SMA crossing above slow SMA, sells on crossing below.
/// </summary>
public class SimpleMartingaleTemplateStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public SimpleMartingaleTemplateStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 15)
.SetGreaterThanZero()
.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new SimpleMovingAverage { Length = FastPeriod };
var slow = new SimpleMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
{
if (candle.State != CandleStates.Finished) return;
if (_hasPrev)
{
if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
BuyMarket();
else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
SellMarket();
}
else
{
if (fastValue > slowValue && Position <= 0)
BuyMarket();
else if (fastValue < slowValue && Position >= 0)
SellMarket();
}
_prevFast = fastValue;
_prevSlow = slowValue;
_hasPrev = true;
}
}