Esta estratégia emula o especialista BuySell do MetaTrader. Combina uma média móvel com o Average True Range (ATR) para detectar reversões de tendência.
Quando a média móvel vira para cima, o sistema considera o mercado altista; quando vira para baixo, considera o mercado baixista.
Uma operação é aberta apenas se a vela anterior estava no estado oposto, confirmando uma reversão. Os níveis opcionais de stop-loss e take-profit são expressos em pontos de preço.
Detalhes
Lógica de entrada
Comprado: a média móvel passa de descendente para ascendente e a vela anterior era baixista.
Vendido: a média móvel passa de ascendente para descendente e a vela anterior era altista.
Lógica de saída
Comprado: a média móvel vira para baixo ou o stop-loss / take-profit é acionado.
Vendido: a média móvel vira para cima ou o stop-loss / take-profit é acionado.
Indicadores: Média Móvel Simples (SMA) e ATR.
Stops: Stop-loss e take-profit em pontos.
Permissões: flags separadas permitem ou proíbem abrir/fechar posições compradas e vendidas.
Período padrão: velas de 4 horas.
Parâmetros
Nome
Padrão
Descrição
MaPeriod
14
Período da média móvel.
AtrPeriod
60
Período do ATR.
StopLoss
1000
Stop-loss em pontos de preço.
TakeProfit
2000
Take-profit em pontos de preço.
AllowLongEntry
true
Permissão para abrir posições compradas.
AllowShortEntry
true
Permissão para abrir posições vendidas.
AllowLongExit
true
Permissão para fechar posições compradas.
AllowShortExit
true
Permissão para fechar posições vendidas.
CandleType
H4
Período utilizado para os cálculos.
Uso
Adicione a estratégia à sua solução StockSharp.
Configure os parâmetros conforme necessário.
Execute a estratégia no modo ao vivo ou de backtesting. As operações são executadas usando ordens BuyMarket e SellMarket.
A abordagem é adequada para mercados onde as reversões de tendência são acompanhadas por mudanças de volatilidade capturadas pelo ATR.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Buy/Sell strategy based on EMA crossover.
/// </summary>
public class BuySellStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public BuySellStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast EMA period", "Indicator");
_slowPeriod = Param(nameof(SlowPeriod), 28)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow EMA period", "Indicator");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
SubscribeCandles(CandleType)
.Bind(fast, slow, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal slowVal)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev)
{
_prevFast = fastVal;
_prevSlow = slowVal;
_hasPrev = true;
return;
}
var crossUp = _prevFast <= _prevSlow && fastVal > slowVal;
var crossDown = _prevFast >= _prevSlow && fastVal < slowVal;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevFast = fastVal;
_prevSlow = slowVal;
}
}