Lacust Stop y BE
Esta estrategia demuestra la gestión básica de posiciones inspirada en el asesor experto MQL original lacuststopandbe.
Tras entrar en una posición en la dirección de la última vela completada, la estrategia aplica varias reglas de protección:
- El stop loss y el take profit iniciales se colocan a distancias de precio fijas.
- Cuando el beneficio alcanza
BreakevenGain, el stop se mueve al precio de entrada másBreakeven. - Después de que el beneficio supera
TrailingStart, el stop sigue al precio a una distancia deTrailingStop. - La posición se cierra cuando se toca el nivel de stop o el nivel de take profit.
Parámetros:
CandleType– serie de velas usada para el procesamiento.StopLoss– distancia inicial del stop loss.TakeProfit– distancia inicial del take profit.TrailingStart– beneficio requerido para activar el trailing stop.TrailingStop– distancia del trailing stop desde el precio actual.BreakevenGain– beneficio requerido antes de mover el stop al break-even.Breakeven– beneficio asegurado después de mover el stop al break-even.
Este ejemplo utiliza la API de alto nivel de StockSharp y puede servir como plantilla para portar scripts simples de gestión de operaciones MQL.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Trade management strategy with break-even and trailing stop logic.
/// Enters on candle direction, manages with SL/TP/trailing/breakeven.
/// </summary>
public class LacustStopAndBeStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<decimal> _takeProfit;
private readonly StrategyParam<decimal> _trailingStart;
private readonly StrategyParam<decimal> _trailingStop;
private readonly StrategyParam<decimal> _breakevenGain;
private readonly StrategyParam<decimal> _breakeven;
private decimal _entryPrice;
private decimal _stopPrice;
private decimal _takePrice;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public decimal StopLoss { get => _stopLoss.Value; set => _stopLoss.Value = value; }
public decimal TakeProfit { get => _takeProfit.Value; set => _takeProfit.Value = value; }
public decimal TrailingStart { get => _trailingStart.Value; set => _trailingStart.Value = value; }
public decimal TrailingStop { get => _trailingStop.Value; set => _trailingStop.Value = value; }
public decimal BreakevenGain { get => _breakevenGain.Value; set => _breakevenGain.Value = value; }
public decimal Breakeven { get => _breakeven.Value; set => _breakeven.Value = value; }
public LacustStopAndBeStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle type", "Candle type", "General");
_stopLoss = Param(nameof(StopLoss), 400m)
.SetDisplay("Stop loss", "Stop loss distance", "Risk");
_takeProfit = Param(nameof(TakeProfit), 2000m)
.SetDisplay("Take profit", "Take profit distance", "Risk");
_trailingStart = Param(nameof(TrailingStart), 300m)
.SetDisplay("Trailing start", "Profit to activate trailing", "Risk");
_trailingStop = Param(nameof(TrailingStop), 200m)
.SetDisplay("Trailing stop", "Trailing stop distance", "Risk");
_breakevenGain = Param(nameof(BreakevenGain), 250m)
.SetDisplay("Breakeven gain", "Profit for breakeven move", "Risk");
_breakeven = Param(nameof(Breakeven), 100m)
.SetDisplay("Breakeven", "Profit locked at breakeven", "Risk");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_entryPrice = 0;
_stopPrice = 0;
_takePrice = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
SubscribeCandles(CandleType)
.Bind(ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
if (Position == 0)
{
if (candle.ClosePrice > candle.OpenPrice)
{
BuyMarket();
_entryPrice = candle.ClosePrice;
_stopPrice = _entryPrice - StopLoss;
_takePrice = _entryPrice + TakeProfit;
}
else if (candle.ClosePrice < candle.OpenPrice)
{
SellMarket();
_entryPrice = candle.ClosePrice;
_stopPrice = _entryPrice + StopLoss;
_takePrice = _entryPrice - TakeProfit;
}
return;
}
if (Position > 0)
{
if (candle.ClosePrice - _entryPrice >= BreakevenGain && _stopPrice < _entryPrice + Breakeven)
_stopPrice = _entryPrice + Breakeven;
if (candle.ClosePrice - _entryPrice >= TrailingStart && _stopPrice < candle.ClosePrice - TrailingStop)
_stopPrice = candle.ClosePrice - TrailingStop;
if (candle.LowPrice <= _stopPrice || candle.HighPrice >= _takePrice)
{
SellMarket();
}
}
else if (Position < 0)
{
if (_entryPrice - candle.ClosePrice >= BreakevenGain && _stopPrice > _entryPrice - Breakeven)
_stopPrice = _entryPrice - Breakeven;
if (_entryPrice - candle.ClosePrice >= TrailingStart && _stopPrice > candle.ClosePrice + TrailingStop)
_stopPrice = candle.ClosePrice + TrailingStop;
if (candle.HighPrice >= _stopPrice || candle.LowPrice <= _takePrice)
{
BuyMarket();
}
}
}
}
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
class lacust_stop_and_be_strategy(Strategy):
def __init__(self):
super(lacust_stop_and_be_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle type", "Candle type", "General")
self._stop_loss = self.Param("StopLoss", 400.0) \
.SetDisplay("Stop loss", "Stop loss distance", "Risk")
self._take_profit = self.Param("TakeProfit", 2000.0) \
.SetDisplay("Take profit", "Take profit distance", "Risk")
self._trailing_start = self.Param("TrailingStart", 300.0) \
.SetDisplay("Trailing start", "Profit to activate trailing", "Risk")
self._trailing_stop = self.Param("TrailingStop", 200.0) \
.SetDisplay("Trailing stop", "Trailing stop distance", "Risk")
self._breakeven_gain = self.Param("BreakevenGain", 250.0) \
.SetDisplay("Breakeven gain", "Profit for breakeven move", "Risk")
self._breakeven = self.Param("Breakeven", 100.0) \
.SetDisplay("Breakeven", "Profit locked at breakeven", "Risk")
self._entry_price = 0.0
self._stop_price = 0.0
self._take_price = 0.0
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def StopLoss(self):
return self._stop_loss.Value
@StopLoss.setter
def StopLoss(self, value):
self._stop_loss.Value = value
@property
def TakeProfit(self):
return self._take_profit.Value
@TakeProfit.setter
def TakeProfit(self, value):
self._take_profit.Value = value
@property
def TrailingStart(self):
return self._trailing_start.Value
@TrailingStart.setter
def TrailingStart(self, value):
self._trailing_start.Value = value
@property
def TrailingStop(self):
return self._trailing_stop.Value
@TrailingStop.setter
def TrailingStop(self, value):
self._trailing_stop.Value = value
@property
def BreakevenGain(self):
return self._breakeven_gain.Value
@BreakevenGain.setter
def BreakevenGain(self, value):
self._breakeven_gain.Value = value
@property
def Breakeven(self):
return self._breakeven.Value
@Breakeven.setter
def Breakeven(self, value):
self._breakeven.Value = value
def OnStarted2(self, time):
super(lacust_stop_and_be_strategy, self).OnStarted2(time)
self.SubscribeCandles(self.CandleType) \
.Bind(self.ProcessCandle) \
.Start()
def ProcessCandle(self, candle):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
open_price = float(candle.OpenPrice)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
sl = float(self.StopLoss)
tp = float(self.TakeProfit)
ts_start = float(self.TrailingStart)
ts_stop = float(self.TrailingStop)
be_gain = float(self.BreakevenGain)
be = float(self.Breakeven)
if self.Position == 0:
if close > open_price:
self.BuyMarket()
self._entry_price = close
self._stop_price = self._entry_price - sl
self._take_price = self._entry_price + tp
elif close < open_price:
self.SellMarket()
self._entry_price = close
self._stop_price = self._entry_price + sl
self._take_price = self._entry_price - tp
return
if self.Position > 0:
if close - self._entry_price >= be_gain and self._stop_price < self._entry_price + be:
self._stop_price = self._entry_price + be
if close - self._entry_price >= ts_start and self._stop_price < close - ts_stop:
self._stop_price = close - ts_stop
if low <= self._stop_price or high >= self._take_price:
self.SellMarket()
elif self.Position < 0:
if self._entry_price - close >= be_gain and self._stop_price > self._entry_price - be:
self._stop_price = self._entry_price - be
if self._entry_price - close >= ts_start and self._stop_price > close + ts_stop:
self._stop_price = close + ts_stop
if high >= self._stop_price or low <= self._take_price:
self.BuyMarket()
def OnReseted(self):
super(lacust_stop_and_be_strategy, self).OnReseted()
self._entry_price = 0.0
self._stop_price = 0.0
self._take_price = 0.0
def CreateClone(self):
return lacust_stop_and_be_strategy()