A Estratégia de Sinal ASCV BrainTrend é uma conversão do especialista do MetaTrader que opera sobre sinais do indicador BrainTrend1. A versão do StockSharp se baseia em vinculações de indicadores de alto nível para combinar o Average True Range (ATR), o Oscilador Estocástico e a Jurik Moving Average (JMA) com o objetivo de detectar reversões de impulso e colocar operações com stops de proteção opcionais.
Ideia Central
Calcular o ATR para medir a volatilidade atual e definir uma banda de confirmação dinâmica.
Suavizar os preços de fechamento com uma Jurik Moving Average e comparar o valor atual com o valor de duas barras atrás.
Quando a diferença suavizada é maior que ATR / 2.3, atualizar o estado da lógica BrainTrend:
%K do Oscilador Estocástico abaixo de 47 alterna o sistema para uma possível configuração vendida.
%K acima de 53 alterna o sistema para uma possível configuração comprada.
Um sinal da barra anterior é executado na próxima vela completada. Os sinais podem ser invertidos com o parâmetro Reverse Signals.
Os níveis de stop-loss, take-profit e trailing-stop são definidos em pips (múltiplos do passo de preço do instrumento).
Regras de Entrada e Saída
Entrada comprada: A barra anterior emitiu um sinal de compra e a estratégia não está já comprada. O tamanho da ordem equivale a Volume + abs(posição atual), de modo que os vendidos são cobertos antes de abrir o novo comprado.
Entrada vendida: A barra anterior emitiu um sinal de venda e a estratégia não está já vendida.
Stop-loss: Colocado em preço de entrada ± StopLossPips * passo de preço. Se o preço ultrapassar o nível de stop dentro da próxima vela, a posição é fechada a mercado.
Take-profit: Take profit opcional em preço de entrada ± TakeProfitPips * passo de preço.
Trailing-stop: Ativado quando tanto TrailingStopPips quanto TrailingStepPips são maiores que zero. Depois que o preço se move TrailingStopPips + TrailingStepPips a favor da operação, o stop é arrastado atrás do movimento por TrailingStopPips.
Parâmetros
Parâmetro
Descrição
Padrão
AtrPeriod
Período de média do ATR para estimativa de volatilidade.
14
StochasticPeriod
Período base para o Oscilador Estocástico.
12
JmaLength
Comprimento de suavização da Jurik Moving Average.
7
StopLossPips
Distância de stop-loss em pips (passos de preço).
15
TakeProfitPips
Distância de take-profit em pips.
46
TrailingStopPips
Distância de trailing stop em pips.
0 (desabilitado)
TrailingStepPips
Movimento favorável mínimo necessário antes do trailing.
5
ReverseSignals
Inverter sinais de compra/venda.
false
CandleType
Período de trabalho, padrão velas de 15 minutos.
15m
Notas
Todos os cálculos de indicadores são realizados em velas terminadas para evitar ruído no meio da barra.
Se o instrumento não fornecer MinPriceStep, um passo padrão de 0.0001 é usado ao converter distâncias de pips.
A estratégia desenha velas, o oscilador estocástico e o JMA no gráfico para monitoramento.
Os trailing stops reproduzem a lógica original do MetaTrader: eles só se movem na direção da operação e exigem que os limiares de distância e passo sejam cumpridos.
Dicas de Uso
Ajustar AtrPeriod e StochasticPeriod para se adequar à volatilidade do instrumento operado.
Aumentar os parâmetros de risco baseados em pips ao operar ativos com tamanhos de tick maiores (p. ex., futuros) para evitar saídas imediatas.
Habilitar ReverseSignals para replicar o modo inverso do Consultor Especialista original.
Combinar com controles de risco do corretor se o trading com dinheiro real estiver envolvido.
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>
/// ASCV BrainTrend Signal strategy. Uses DEMA crossover (8/25).
/// </summary>
public class AscvBrainTrendSignalStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private decimal? _prevFast;
private decimal? _prevSlow;
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 AscvBrainTrendSignalStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 8).SetGreaterThanZero().SetDisplay("Fast DEMA", "Fast DEMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 25).SetGreaterThanZero().SetDisplay("Slow DEMA", "Slow DEMA period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = null;
_prevSlow = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = null; _prevSlow = null;
var fast = new DoubleExponentialMovingAverage { Length = FastPeriod };
var slow = new DoubleExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) { _prevFast = fast; _prevSlow = slow; return; }
if (_prevFast == null || _prevSlow == null) { _prevFast = fast; _prevSlow = slow; return; }
var prevAbove = _prevFast.Value > _prevSlow.Value;
var currAbove = fast > slow;
_prevFast = fast; _prevSlow = slow;
if (!prevAbove && currAbove && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
else if (prevAbove && !currAbove && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import DoubleExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class ascv_brain_trend_signal_strategy(Strategy):
def __init__(self):
super(ascv_brain_trend_signal_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._fast_period = self.Param("FastPeriod", 8) \
.SetDisplay("Fast DEMA", "Fast DEMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 25) \
.SetDisplay("Slow DEMA", "Slow DEMA period", "Indicators")
self._prev_fast = None
self._prev_slow = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
def OnReseted(self):
super(ascv_brain_trend_signal_strategy, self).OnReseted()
self._prev_fast = None
self._prev_slow = None
def OnStarted2(self, time):
super(ascv_brain_trend_signal_strategy, self).OnStarted2(time)
self._prev_fast = None
self._prev_slow = None
fast = DoubleExponentialMovingAverage()
fast.Length = self.FastPeriod
slow = DoubleExponentialMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, slow, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def _on_process(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
fv = float(fast_value)
sv = float(slow_value)
if self._prev_fast is None or self._prev_slow is None:
self._prev_fast = fv
self._prev_slow = sv
return
prev_above = self._prev_fast > self._prev_slow
curr_above = fv > sv
self._prev_fast = fv
self._prev_slow = sv
if not prev_above and curr_above and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif prev_above and not curr_above and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return ascv_brain_trend_signal_strategy()