A estratégia MelBar Take325 é uma conversão direta do sistema Expert Advisor Studio "MelBar™Take325%™ 5.5Y NZD-USD". Ele negocia em ambas as direções no NZD/USD usando uma combinação de quebras de volume de ticks, um filtro de oscilação baseado em uma média móvel simples de 12 períodos e um filtro de saída RSI de 14 períodos. A porta StockSharp mantém os parâmetros de risco originais de um stop loss de 16 pips e um take-profit de 45 pips, expressos em distâncias de pips do preço de entrada.
A estratégia começa aguardando um aumento no volume de ticks, definido como um rompimento acima do limite de volume configurado. Quando o volume se expande, ele verifica se a média móvel simples formou um ponto de inflexão local duas barras antes. Um máximo local em SMA abre uma negociação longa, enquanto um mínimo local abre uma negociação curta. Apenas uma direção pode ser tomada por vez, e sinais conflitantes são ignorados para evitar inversões na mesma barra.
As posições abertas são gerenciadas ativamente. Os níveis de stop-loss e take-profit são aplicados sempre que uma vela fecha, tornando o comportamento semelhante à versão MetaTrader. Além disso, o RSI de 14 períodos é usado para forçar saídas: as negociações longas fecham quando RSI cruza para baixo o nível configurado (padrão 80) e as negociações curtas fecham quando RSI cruza para cima o nível simétrico (padrão 20). A máxima/mínima da vela processada é comparada com o preço de entrada para acionar saídas de stop-loss e take-profit.
Detalhes
Critérios de entrada:
Filtro de volume: o volume do tick duas barras atrás deve estar abaixo do limite enquanto a barra anterior o excede.
Longo: SMA (comprimento 12) tem um pico local há duas barras (SMA[t-3] < SMA[t-2] e SMA[t-2] > SMA[t-1]).
Curto: SMA tem um vale local (SMA[t-3] > SMA[t-2] e SMA[t-2] < SMA[t-1]).
Critérios de saída:
Stop-loss: 16 pips a partir da entrada, avaliado no fechamento da vela.
Take-profit: 45 pips desde a entrada, avaliados no fechamento da vela.
Saída RSI longa: RSI cruza para baixo até 80 (RSI[t-3] > 80 e RSI[t-2] < 80).
Saída RSI curta: RSI cruza para cima até 20 (RSI[t-3] < 20 e RSI[t-2] > 20).
Parâmetros padrão:
Volume de entrada = 0,1 lote.
Limite de volume = 1.000 unidades de volume de tick.
SMA período = 12.
RSI período = 14.
RSI nível = 80 (a saída curta usa 100 - nível).
Prazo da vela = 30 minutos.
Mercado: Projetado para NZD/USD, mas pode ser aplicado a outros pares de FX.
Estilo: Quebra de impulso com saídas de reversão à média.
Stops: Stop-loss e take-profit fixos; nenhuma parada final no código original.
Complexidade: Moderada; combina vários filtros, mas sem escala de posição.
Risco: Médio, pois o stop é mais apertado que o take-profit, mas ambos são distâncias fixas.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// MelBar Take325 strategy: SMA reversal with RSI exit filter.
/// Enters on SMA direction change, exits when RSI reaches extreme levels.
/// </summary>
public class MelBarTake325Strategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _smaPeriod;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _rsiExitLevel;
private readonly StrategyParam<int> _signalCooldownCandles;
private decimal _prevSma;
private decimal _prevPrevSma;
private bool _hasPrev2;
private int _candlesSinceTrade;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int SmaPeriod { get => _smaPeriod.Value; set => _smaPeriod.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal RsiExitLevel { get => _rsiExitLevel.Value; set => _rsiExitLevel.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public MelBarTake325Strategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_smaPeriod = Param(nameof(SmaPeriod), 12)
.SetGreaterThanZero()
.SetDisplay("SMA Period", "SMA period", "Indicators");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
_rsiExitLevel = Param(nameof(RsiExitLevel), 75m)
.SetDisplay("RSI Exit Level", "RSI level to close long; 100-level closes short", "Signals");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 8)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevSma = 0m;
_prevPrevSma = 0m;
_hasPrev2 = false;
_candlesSinceTrade = SignalCooldownCandles;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev2 = false;
_candlesSinceTrade = SignalCooldownCandles;
var sma = new SimpleMovingAverage { Length = SmaPeriod };
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(sma, rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal sma, decimal rsi)
{
if (candle.State != CandleStates.Finished) return;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
if (_hasPrev2)
{
// Exit on RSI extremes
if (Position > 0 && rsi > RsiExitLevel)
{
SellMarket();
_candlesSinceTrade = 0;
}
else if (Position < 0 && rsi < (100 - RsiExitLevel))
{
BuyMarket();
_candlesSinceTrade = 0;
}
// Entry on SMA reversal (peak/trough)
if (Position == 0 && _candlesSinceTrade >= SignalCooldownCandles && _prevPrevSma > _prevSma && _prevSma < sma)
{
BuyMarket();
_candlesSinceTrade = 0;
}
else if (Position == 0 && _candlesSinceTrade >= SignalCooldownCandles && _prevPrevSma < _prevSma && _prevSma > sma)
{
SellMarket();
_candlesSinceTrade = 0;
}
}
_prevPrevSma = _prevSma;
_prevSma = sma;
_hasPrev2 = true;
}
}