Convierte el asesor experto MetaTrader BuySellonYourPrice.mq5 (id 35391) en la API de alto nivel de StockSharp.
Envía exactamente una orden al inicio, coincidiendo con la lógica original que no requiere órdenes ni posiciones activas.
Admite entradas de mercado, límite y parada con niveles opcionales de parada de pérdidas y toma de ganancias expresados como precios absolutos.
Configura automáticamente StockSharp órdenes de protección cuando se pueden derivar distancias válidas de stop-loss/take-profit a partir de los niveles de precios proporcionados.
Parámetros
Nombre
Descripción
Predeterminado
Mode
Tipo de orden a enviar (Ninguno, Comprar, Vender, BuyLimit, SellLimit, BuyStop, SellStop).
None
OrderVolume
Volumen del pedido generado.
1
EntryPrice
Precio utilizado para órdenes pendientes; ignorado para las órdenes de mercado.
0
StopLossPrice
Nivel de precio absoluto del stop-loss.
0
TakeProfitPrice
Nivel de precio absoluto para la toma de ganancias.
0
Lógica de trading
Cuando la estrategia comienza comprueba que:
Se selecciona un Mode válido diferente de None.
OrderVolume es positivo.
No hay ninguna posición actual ni órdenes activas. Si cualquiera de ellos está presente, el pedido no se envía (igual que OrdersTotal()==0 y PositionsTotal()==0 verificar en MQL).
El precio de entrada se resuelve:
Los modos de mercado utilizan la mejor oferta/demanda, retrocediendo al último precio o EntryPrice cuando aún no hay datos de mercado disponibles.
Los modos pendientes requieren EntryPrice > 0.
Las distancias de protección se derivan de los niveles de stop-loss y take-profit especificados. Solo se pasan distancias positivas válidas a StartProtection para emular los parámetros EA.
El tipo de orden seleccionado se envía (BuyMarket, SellLimit, BuyStop, etc.) exactamente una vez y se generan registros informativos para reflejar la acción.
Diferencias con el original EA
El registro se realiza a través de AddInfoLog en lugar de Print.
Las órdenes de protección se registran vía StartProtection cuando tanto el precio de entrada como el stop-loss/take-profit permiten calcular una distancia positiva.
La resolución de precios de mercado utiliza datos actuales de Nivel 1 (BestBid, BestAsk, LastPrice) y pospone el envío de pedidos si aún no hay una cotización disponible.
Notas de uso
Asigne el valor deseado antes de comenzar la estrategia y asegúrese de que los datos de Nivel 1 estén disponibles para las órdenes de mercado.
Establezca EntryPrice, StopLossPrice y TakeProfitPrice en términos absolutos cuando utilice órdenes pendientes.
Deje Mode como None para deshabilitar el comercio sin eliminar la estrategia del entorno.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Buy Sell On Your Price strategy: Keltner Channel breakout.
/// Buys when close breaks above upper Keltner band, sells when close breaks below lower band.
/// </summary>
public class BuySellOnYourPriceStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaPeriod;
private decimal _prevClose;
private decimal _prevEma;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public BuySellOnYourPriceStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_emaPeriod = Param(nameof(EmaPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA period for trend", "Indicators");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = 0;
_prevEma = 0;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevClose = 0;
_prevEma = 0;
_hasPrev = false;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue)
{
if (candle.State != CandleStates.Finished) return;
if (_hasPrev)
{
if (_prevClose <= _prevEma && candle.ClosePrice > emaValue && Position <= 0)
BuyMarket();
else if (_prevClose >= _prevEma && candle.ClosePrice < emaValue && Position >= 0)
SellMarket();
}
_prevClose = candle.ClosePrice;
_prevEma = emaValue;
_hasPrev = true;
}
}
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
from StockSharp.Algo.Strategies import Strategy
class buy_sell_on_your_price_strategy(Strategy):
def __init__(self):
super(buy_sell_on_your_price_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(60)))
self._ema_period = self.Param("EmaPeriod", 50)
self._prev_close = 0.0
self._prev_ema = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def EmaPeriod(self):
return self._ema_period.Value
@EmaPeriod.setter
def EmaPeriod(self, value):
self._ema_period.Value = value
def OnReseted(self):
super(buy_sell_on_your_price_strategy, self).OnReseted()
self._prev_close = 0.0
self._prev_ema = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(buy_sell_on_your_price_strategy, self).OnStarted2(time)
self._prev_close = 0.0
self._prev_ema = 0.0
self._has_prev = False
ema = ExponentialMovingAverage()
ema.Length = self.EmaPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, self._process_candle).Start()
def _process_candle(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
ema_val = float(ema_value)
if self._has_prev:
if self._prev_close <= self._prev_ema and close > ema_val and self.Position <= 0:
self.BuyMarket()
elif self._prev_close >= self._prev_ema and close < ema_val and self.Position >= 0:
self.SellMarket()
self._prev_close = close
self._prev_ema = ema_val
self._has_prev = True
def CreateClone(self):
return buy_sell_on_your_price_strategy()