Início
/
Exemplos de estratégias
Ver no GitHub
Estratégia de fuga de lucro
Esta estratégia replica o especialista em "take-profit" MetaTrader procurando quatro velas consecutivas com máximas e aberturas estritamente monótonas. Quando a vela atual termina com máximos ascendentes e abre, o algoritmo trata a sequência como um impulso de alta e envia uma compra de mercado. Uma condição espelhada com máximas e aberturas em queda produz uma venda no mercado. Os pedidos são gerenciados com uma meta de lucro no nível da conta, um trailing stop que pode fechar parcialmente a exposição e um stop loss fixo opcional definido em etapas de preço.
A configuração padrão é negociada em velas de um minuto. A estratégia pode ser ajustada para diferentes instrumentos ajustando o tipo de vela, índices de mudança que controlam quais velas são comparadas, distância final, distância de stop-loss, meta de lucro e modo de dimensionamento de posição. Ele suporta um tamanho de lote fixo ou um volume dinâmico calculado a partir do patrimônio do portfólio e da porcentagem de risco definida pelo usuário. Quando o trailing stop avança, o algoritmo pode opcionalmente fechar metade da posição restante para garantir lucros enquanto mantém um runner ativo.
Atingir a meta de lucro configurada medida no patrimônio do portfólio liquida imediatamente a posição atual e cancela quaisquer ordens de trabalho. Isso reflete o especialista MQL original que fechou todas as negociações quando o patrimônio da conta excedeu o saldo mais o ganho desejado. A ramificação de gerenciamento de riscos valida a porcentagem de risco configurada e garante que o volume solicitado respeite a etapa do volume de segurança.
Detalhes
Lógica de entrada :
Longo : as quatro velas monitoradas mostram máximas estritamente crescentes e aberturas estritamente crescentes.
Curto : as quatro velas monitoradas mostram máximas estritamente decrescentes e aberturas estritamente decrescentes.
Gerenciamento de posição :
Stop-loss opcional colocado ao preço de entrada menos/mais o número configurado de etapas de preço.
O trailing stop segue o preço de fechamento quando ele se move mais do que a distância final da entrada.
A saída parcial (50% do volume restante) é executada toda vez que o trailing stop se move, sujeito à etapa de volume do título e ao lote mínimo negociável.
Account Target : encerra todas as exposições e cancela pedidos ativos quando portfolio equity ≥ initial equity + ProfitTarget.
Gerenciamento de Riscos :
O modo de lote fixo usa o parâmetro Lots configurado (ou Volume da base da estratégia, se especificado).
O modo percentual de risco dimensiona o pedido como equity * RiskPercent / max(stopDistance, price) e normaliza o resultado pela etapa de volume.
Parâmetros padrão :
Shift1 = 0, Shift2 = 1, Shift3 = 2, Shift4 = 3.
TrailingStopPoints = 1, StopLossPoints = 0, ProfitTarget = 1 (unidades monetárias da conta).
Lots = 1, RiskPercent = 1, MaxOrders = 1.
CandleType = período de 1 minuto.
Melhores Mercados : tendências de futuros, principais FX e pares de criptomoedas líquidas onde o impulso de curto prazo persiste em várias velas.
Pontos fortes : detecção rápida de impulso, meta de patrimônio configurável, expansão parcial e controles de risco simples.
Pontos fracos : sensível a faixas ruidosas, depende dos tamanhos corretos dos passos e assume o modo de compensação (posição agregada única).
Parâmetros
Nome
Descrição
Shift1 – Shift4
Índices das velas comparados para a sequência de breakout.
TrailingStopPoints
Distância final em etapas de preço.
StopLossPoints
Distância de parada inicial em etapas de preço; zero desativa o stop loss.
ProfitTarget
Meta de lucro aplicada ao patrimônio do portfólio antes de fechar todas as negociações.
Lots
Volume de negociação fixo quando o gerenciamento de risco está desativado.
RiskManagement
Permite o dimensionamento baseado em risco usando RiskPercent.
RiskPercent
Percentagem de capital da carteira arriscada em cada negociação quando a gestão de risco está ativa.
PartialClose
Se habilitado, fecha metade da posição sempre que o trailing stop se move.
MaxOrders
Número máximo de unidades base permitidas simultaneamente (limite de posição líquida).
CandleType
Período de tempo usado para geração de sinal.
Dicas de uso
Alinhe os parâmetros Shift com a volatilidade do instrumento. Mudanças maiores analisam sequências de momentum mais longas.
Defina TrailingStopPoints em relação à etapa de preço do título; valores muito pequenos podem gerar saídas parciais rápidas.
Use o dimensionamento percentual de risco com um StopLossPoints explícito para que o tamanho da posição reflita o risco monetário real por negociação.
Monitore a curva de patrimônio: uma vez atingida a meta global, a estratégia para de negociar até ser reiniciada, imitando o EA original.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Take Profit Breakout: Consecutive candle breakout with EMA filter and ATR stops.
/// </summary>
public class TakeProfitBreakoutStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastEmaLength;
private readonly StrategyParam<int> _slowEmaLength;
private readonly StrategyParam<int> _atrLength;
private decimal _prevFast;
private decimal _prevSlow;
private decimal _entryPrice;
public TakeProfitBreakoutStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Timeframe.", "General");
_fastEmaLength = Param(nameof(FastEmaLength), 10)
.SetDisplay("Fast EMA Length", "Fast EMA period.", "Indicators");
_slowEmaLength = Param(nameof(SlowEmaLength), 30)
.SetDisplay("Slow EMA Length", "Slow EMA period.", "Indicators");
_atrLength = Param(nameof(AtrLength), 14)
.SetDisplay("ATR Length", "ATR period.", "Indicators");
}
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int FastEmaLength { get => _fastEmaLength.Value; set => _fastEmaLength.Value = value; }
public int SlowEmaLength { get => _slowEmaLength.Value; set => _slowEmaLength.Value = value; }
public int AtrLength { get => _atrLength.Value; set => _atrLength.Value = value; }
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0; _prevSlow = 0; _entryPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = 0; _prevSlow = 0; _entryPrice = 0;
var fastEma = new ExponentialMovingAverage { Length = FastEmaLength };
var slowEma = new ExponentialMovingAverage { Length = SlowEmaLength };
var atr = new AverageTrueRange { Length = AtrLength };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fastEma, slowEma, atr, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fastEma); DrawIndicator(area, slowEma); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal slowVal, decimal atrVal)
{
if (candle.State != CandleStates.Finished) return;
if (_prevFast == 0 || _prevSlow == 0 || atrVal <= 0) { _prevFast = fastVal; _prevSlow = slowVal; return; }
var close = candle.ClosePrice;
if (Position > 0)
{
if ((fastVal < slowVal && _prevFast >= _prevSlow) || close <= _entryPrice - atrVal * 2m) { SellMarket(); _entryPrice = 0; }
}
else if (Position < 0)
{
if ((fastVal > slowVal && _prevFast <= _prevSlow) || close >= _entryPrice + atrVal * 2m) { BuyMarket(); _entryPrice = 0; }
}
if (Position == 0)
{
if (fastVal > slowVal && _prevFast <= _prevSlow) { _entryPrice = close; BuyMarket(); }
else if (fastVal < slowVal && _prevFast >= _prevSlow) { _entryPrice = close; SellMarket(); }
}
_prevFast = fastVal; _prevSlow = slowVal;
}
}
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.Strategies import Strategy
from StockSharp.Algo.Indicators import ExponentialMovingAverage, AverageTrueRange
class take_profit_breakout_strategy(Strategy):
def __init__(self):
super(take_profit_breakout_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe.", "General")
self._fast_ema_length = self.Param("FastEmaLength", 10) \
.SetDisplay("Fast EMA Length", "Fast EMA period.", "Indicators")
self._slow_ema_length = self.Param("SlowEmaLength", 30) \
.SetDisplay("Slow EMA Length", "Slow EMA period.", "Indicators")
self._atr_length = self.Param("AtrLength", 14) \
.SetDisplay("ATR Length", "ATR period.", "Indicators")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._entry_price = 0.0
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastEmaLength(self):
return self._fast_ema_length.Value
@property
def SlowEmaLength(self):
return self._slow_ema_length.Value
@property
def AtrLength(self):
return self._atr_length.Value
def OnStarted2(self, time):
super(take_profit_breakout_strategy, self).OnStarted2(time)
self._prev_fast = 0.0
self._prev_slow = 0.0
self._entry_price = 0.0
self._fast_ema = ExponentialMovingAverage()
self._fast_ema.Length = self.FastEmaLength
self._slow_ema = ExponentialMovingAverage()
self._slow_ema.Length = self.SlowEmaLength
self._atr = AverageTrueRange()
self._atr.Length = self.AtrLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self._fast_ema, self._slow_ema, self._atr, self.ProcessCandle).Start()
def ProcessCandle(self, candle, fast_val, slow_val, atr_val):
if candle.State != CandleStates.Finished:
return
fv = float(fast_val)
sv = float(slow_val)
av = float(atr_val)
if self._prev_fast == 0 or self._prev_slow == 0 or av <= 0:
self._prev_fast = fv
self._prev_slow = sv
return
close = float(candle.ClosePrice)
if self.Position > 0:
if (fv < sv and self._prev_fast >= self._prev_slow) or close <= self._entry_price - av * 2.0:
self.SellMarket()
self._entry_price = 0.0
elif self.Position < 0:
if (fv > sv and self._prev_fast <= self._prev_slow) or close >= self._entry_price + av * 2.0:
self.BuyMarket()
self._entry_price = 0.0
if self.Position == 0:
if fv > sv and self._prev_fast <= self._prev_slow:
self._entry_price = close
self.BuyMarket()
elif fv < sv and self._prev_fast >= self._prev_slow:
self._entry_price = close
self.SellMarket()
self._prev_fast = fv
self._prev_slow = sv
def OnReseted(self):
super(take_profit_breakout_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._entry_price = 0.0
def CreateClone(self):
return take_profit_breakout_strategy()