La Estrategia Fortrader 10 Pips es una StockSharp versión del MetaTrader 4 asesor experto 10pips.mq4 (ID de estrategia 8074). El robot mantiene abiertas simultáneamente una posición larga y una corta. Cada tramo utiliza distancias fijas de toma de ganancias, stop-loss y trailing-stop medidas en puntos de símbolo.
Esta conversión recrea el comportamiento de cobertura dentro del nivel alto de StockSharp API. Inmediatamente después de que comienza la estrategia, envía una orden de compra y venta de mercado. Siempre que una orden de protección cierra un tramo, la estrategia abre instantáneamente una nueva orden en la misma dirección, manteniendo vivas dos posiciones opuestas en todo momento.
Parámetros
Nombre
Descripción
Take Profit Buy
Distancia de toma de ganancias para el tramo largo, en puntos.
Stop Loss Buy
Distancia de stop-loss para el tramo largo, en puntos.
Trailing Stop Buy
Distancia del trailing-stop para el tramo largo, en puntos. Establezca en cero para desactivar el seguimiento.
Take Profit Sell
Distancia de toma de ganancias para el tramo corto, en puntos.
Stop Loss Sell
Distancia de stop-loss para el tramo corto, en puntos.
Trailing Stop Sell
Distancia del trailing-stop para el tramo corto, en puntos. Establezca en cero para desactivar el seguimiento.
Volume
Volumen de cada orden de mercado en lotes.
Todas las distancias se multiplican por el PriceStep del instrumento para convertir de puntos a valores de precio absoluto. Cada parámetro se expone a través de StrategyParam<T> para que la estrategia se pueda ajustar u optimizar a través de la GUI.
Lógica de trading
Inicio: OnStarted se suscribe a los datos de nivel 1 para realizar un seguimiento de los mejores precios de oferta y demanda actuales. La estrategia envía inmediatamente una orden de compra de mercado y una orden de venta de mercado.
Órdenes de protección: después de cada entrada completa (OnNewMyTrade), la estrategia crea las órdenes de stop-loss y take-profit asociadas si las distancias son mayores que cero. Las órdenes se redondean al paso de precio más cercano.
Reentrada: cuando se ejecuta una orden de limitación de pérdidas o de toma de ganancias, el tramo cerrado se reabre instantáneamente con una nueva orden de mercado para que persista la exposición bidireccional.
Paradas dinámicas: las actualizaciones de nivel 1 activan UpdateTrailingStops, que ajusta las órdenes de limitación de pérdidas cada vez que la oferta/demanda actual se ha movido más allá de la distancia final configurada desde el precio de entrada. La lógica refleja la EA original: el seguimiento comienza una vez que las ganancias exceden la distancia de seguimiento, y las paradas se mueven solo en la dirección de las ganancias.
Notas de implementación
El código MT4 original esperó 10 segundos entre las órdenes iniciales de compra y venta. StockSharp no requiere este retraso, por lo tanto ambos pedidos se envían de inmediato.
Debido a que StockSharp utiliza posiciones netas de forma predeterminada, la verdadera cobertura puede depender de que el corredor/conector respalde posiciones opuestas. La estrategia realiza un seguimiento de cada tramo de forma independiente y los restablece después de cada salida.
StartProtection() se llama una vez durante OnStarted para que las protecciones de riesgos globales estén activas si se configuran en la configuración del marco.
Consejos de uso
Asegúrese de que el conector seleccionado admita posiciones largas y cortas simultáneas si se requiere el comportamiento de cobertura.
Establezca las distancias de seguimiento en cero para desactivar el seguimiento del tramo correspondiente.
Optimice los parámetros de riesgo (Take Profit, Stop Loss, Trailing Stop) en datos históricos para que se ajusten al símbolo negociado y al período de tiempo.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class Fortrader10PipsStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast; private decimal _prevSlow; private bool _hasPrev;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Fortrader10PipsStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 7).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 21).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }
if (_prevFast <= _prevSlow && fast > slow && Position <= 0)
{ if (Position < 0) BuyMarket(); BuyMarket(); }
else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
{ if (Position > 0) SellMarket(); SellMarket(); }
_prevFast = fast; _prevSlow = slow;
}
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
}
}
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 fortrader_10_pips_strategy(Strategy):
"""
Fortrader 10 Pips: Simple EMA crossover (fast 7, slow 21).
Buys when fast crosses above slow, sells on reverse.
"""
def __init__(self):
super(fortrader_10_pips_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 7) \
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 21) \
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(fortrader_10_pips_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(fortrader_10_pips_strategy, self).OnStarted2(time)
self._has_prev = False
fast = ExponentialMovingAverage()
fast.Length = self._fast_period.Value
slow = ExponentialMovingAverage()
slow.Length = self._slow_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast, slow, self._process_candle).Start()
def _process_candle(self, candle, fast_val, slow_val):
if candle.State != CandleStates.Finished:
return
fast_val = float(fast_val)
slow_val = float(slow_val)
if not self._has_prev:
self._prev_fast = fast_val
self._prev_slow = slow_val
self._has_prev = True
return
if self._prev_fast <= self._prev_slow and fast_val > slow_val and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and fast_val < slow_val and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_fast = fast_val
self._prev_slow = slow_val
def CreateClone(self):
return fortrader_10_pips_strategy()