Parabolic SAR Estratégia de alerta de inversão (4164)
Visão geral
Esta estratégia reproduz o consultor especialista MetaTrader pSAR_alert2 dentro da estrutura StockSharp. Ele monitora o indicador Parabolic SAR no instrumento e período selecionados. Sempre que o valor SAR passa de acima do preço de fechamento para abaixo dele (ou vice-versa), a estratégia gera um alerta informativo. Opcionalmente, pode enviar ordens de mercado na direção da virada para transformar o alerta em uma entrada automatizada.
Lógica de negociação
Assine a série de velas configurada e calcule o indicador Parabolic SAR com as configurações de aceleração fornecidas.
Espere que cada vela termine para emular o tempo original EA.
Compare o valor do indicador com o fechamento da vela:
O anterior SAR acima do fechamento e o atual SAR abaixo do fechamento → mudança de alta.
O anterior SAR abaixo do fechamento e o atual SAR acima do fechamento → inversão de baixa.
Registre um alerta detalhado para cada virada. Quando a negociação automática estiver ativada, nivele qualquer exposição oposta e abra uma nova posição na direção do sinal usando ordens de mercado.
Parâmetros
Parâmetro
Descrição
Candle Type
Prazo usado para construir velas e avaliar o indicador Parabolic SAR.
SAR Step
Fator de aceleração inicial passado para Parabolic SAR.
SAR Max
Fator máximo de aceleração do Parabolic SAR.
Enable Auto Trading
Quando true, as ordens de mercado são enviadas em cada alerta; quando false, apenas logs são gerados.
Trade Volume
Tamanho do pedido aplicado quando a negociação automática está habilitada.
Notas de conversão
O script MetaTrader original dependia de Sleep para limitar a execução. StockSharp é orientado a eventos, portanto a estratégia reage a novas velas imediatamente, sem atrasos manuais.
Os alertas são produzidos por meio de AddInfoLog, mantendo o comportamento original das notificações pop-up sem exigir componentes de UI adicionais.
A negociação automática opcional é fornecida para integrar a lógica de alerta em fluxos de trabalho automatizados. Desative o parâmetro Enable Auto Trading para corresponder ao comportamento exato de MetaTrader.
A implementação do Python é omitida intencionalmente conforme solicitado.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Parabolic SAR Flip: EMA trend following with ATR stops.
/// </summary>
public class ParabolicSarFlipAlertStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _atrLength;
private decimal _prevClose;
private decimal _entryPrice;
public ParabolicSarFlipAlertStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Timeframe.", "General");
_emaLength = Param(nameof(EmaLength), 20)
.SetDisplay("EMA Length", "Trend filter.", "Indicators");
_atrLength = Param(nameof(AtrLength), 14)
.SetDisplay("ATR Length", "ATR period.", "Indicators");
}
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaLength { get => _emaLength.Value; set => _emaLength.Value = value; }
public int AtrLength { get => _atrLength.Value; set => _atrLength.Value = value; }
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = 0; _entryPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevClose = 0; _entryPrice = 0;
var ema = new ExponentialMovingAverage { Length = EmaLength };
var atr = new AverageTrueRange { Length = AtrLength };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, atr, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, ema); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal, decimal atrVal)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
if (_prevClose == 0 || atrVal <= 0) { _prevClose = close; return; }
if (Position > 0)
{
if (close >= _entryPrice + atrVal * 2.5m || close <= _entryPrice - atrVal * 1.5m || close < emaVal) { SellMarket(); _entryPrice = 0; }
}
else if (Position < 0)
{
if (close <= _entryPrice - atrVal * 2.5m || close >= _entryPrice + atrVal * 1.5m || close > emaVal) { BuyMarket(); _entryPrice = 0; }
}
if (Position == 0)
{
if (close > emaVal && _prevClose <= emaVal) { _entryPrice = close; BuyMarket(); }
else if (close < emaVal && _prevClose >= emaVal) { _entryPrice = close; SellMarket(); }
}
_prevClose = close;
}
}
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 ExponentialMovingAverage, AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class parabolic_sar_flip_alert_strategy(Strategy):
def __init__(self):
super(parabolic_sar_flip_alert_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Timeframe", "General")
self._ema_length = self.Param("EmaLength", 20).SetDisplay("EMA Length", "Trend filter", "Indicators")
self._atr_length = self.Param("AtrLength", 14).SetDisplay("ATR Length", "ATR period", "Indicators")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(parabolic_sar_flip_alert_strategy, self).OnReseted()
self._prev_close = 0
self._entry_price = 0
def OnStarted2(self, time):
super(parabolic_sar_flip_alert_strategy, self).OnStarted2(time)
self._prev_close = 0
self._entry_price = 0
ema = ExponentialMovingAverage()
ema.Length = self._ema_length.Value
atr = AverageTrueRange()
atr.Length = self._atr_length.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(ema, atr, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def OnProcess(self, candle, ema_val, atr_val):
if candle.State != CandleStates.Finished:
return
close = candle.ClosePrice
if self._prev_close == 0 or atr_val <= 0:
self._prev_close = close
return
if self.Position > 0:
if close >= self._entry_price + atr_val * 2.5 or close <= self._entry_price - atr_val * 1.5 or close < ema_val:
self.SellMarket()
self._entry_price = 0
elif self.Position < 0:
if close <= self._entry_price - atr_val * 2.5 or close >= self._entry_price + atr_val * 1.5 or close > ema_val:
self.BuyMarket()
self._entry_price = 0
if self.Position == 0:
if close > ema_val and self._prev_close <= ema_val:
self._entry_price = close
self.BuyMarket()
elif close < ema_val and self._prev_close >= ema_val:
self._entry_price = close
self.SellMarket()
self._prev_close = close
def CreateClone(self):
return parabolic_sar_flip_alert_strategy()