Inicio
/
Ejemplos de estrategias
Ver en GitHub
Estrategia EURUSD V2.0
Sistema de reversión a la media para EURUSD que utiliza una media móvil simple (SMA) de largo plazo y un filtro de volatilidad basado en el Rango Verdadero Promedio (ATR).
Lógica de la estrategia
Calcular una SMA de longitud MA Length en el tipo de vela elegido.
Entrar corto cuando el precio está por encima de la SMA y retrocede dentro de Buffer pips mientras el ATR está por debajo de ATR Threshold .
Entrar largo cuando el precio está por debajo de la SMA y se acerca dentro de Buffer pips con ATR bajo.
El tamaño de la posición se deriva del balance de la cuenta y el Risk Factor Z .
El stop-loss y el take-profit se colocan a distancias fijas en pips desde el precio de entrada.
Tras la salida, el sistema espera que el precio se aleje Noise Filter pips del nivel de entrada antes de permitir una nueva operación.
Parámetros
MA Length – período de la media móvil simple (predeterminado 218).
Buffer (pips) – distancia máxima desde la SMA para activar la entrada (predeterminado 0).
Stop Loss (pips) – distancia del stop-loss desde la entrada (predeterminado 20).
Take Profit (pips) – distancia del take-profit desde la entrada (predeterminado 350).
Noise Filter (pips) – distancia para restablecer el permiso de trading (predeterminado 50).
ATR Length – período de cálculo del ATR (predeterminado 200).
ATR Threshold (pips) – ATR máximo para permitir nuevas posiciones (predeterminado 40).
Max Spread (pips) – spread máximo permitido (predeterminado 4).
Risk Factor Z – factor de gestión monetaria (predeterminado 2).
Candle Type – período de las velas procesadas (predeterminado 15 minutos).
Esta estrategia utiliza órdenes de mercado para entradas y salidas.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// SMA mean-reversion strategy with ATR filter.
/// Buys below SMA, sells above SMA when ATR confirms range conditions.
/// </summary>
public class EurusdV20Strategy : Strategy
{
private readonly StrategyParam<int> _maLength;
private readonly StrategyParam<int> _atrLength;
private readonly StrategyParam<decimal> _takeProfit;
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<DataType> _candleType;
private decimal _entryPrice;
public int MaLength { get => _maLength.Value; set => _maLength.Value = value; }
public int AtrLength { get => _atrLength.Value; set => _atrLength.Value = value; }
public decimal TakeProfit { get => _takeProfit.Value; set => _takeProfit.Value = value; }
public decimal StopLoss { get => _stopLoss.Value; set => _stopLoss.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public EurusdV20Strategy()
{
_maLength = Param(nameof(MaLength), 50)
.SetGreaterThanZero()
.SetDisplay("MA Length", "SMA period", "General");
_atrLength = Param(nameof(AtrLength), 14)
.SetGreaterThanZero()
.SetDisplay("ATR Length", "ATR period", "Indicators");
_takeProfit = Param(nameof(TakeProfit), 500m)
.SetDisplay("Take Profit", "Take profit in price units", "Risk");
_stopLoss = Param(nameof(StopLoss), 300m)
.SetDisplay("Stop Loss", "Stop loss in price units", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_entryPrice = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sma = new SimpleMovingAverage { Length = MaLength };
var sub = SubscribeCandles(CandleType);
sub.Bind(sma, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal smaValue)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
// Exit management
if (Position > 0)
{
if (close - _entryPrice >= TakeProfit || _entryPrice - close >= StopLoss)
{
SellMarket();
_entryPrice = 0;
return;
}
}
else if (Position < 0)
{
if (_entryPrice - close >= TakeProfit || close - _entryPrice >= StopLoss)
{
BuyMarket();
_entryPrice = 0;
return;
}
}
if (Position != 0)
return;
// Mean reversion: buy below SMA, sell above SMA
var dist = Math.Abs(close - smaValue);
if (dist < smaValue * 0.002m)
return;
if (close < smaValue)
{
BuyMarket();
_entryPrice = close;
}
else if (close > smaValue)
{
SellMarket();
_entryPrice = 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, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class eurusd_v2_0_strategy(Strategy):
"""
SMA mean-reversion strategy with TP/SL.
Buys below SMA, sells above SMA when distance exceeds threshold.
Exits on take profit or stop loss.
"""
def __init__(self):
super(eurusd_v2_0_strategy, self).__init__()
self._ma_length = self.Param("MaLength", 50) \
.SetDisplay("MA Length", "SMA period", "General")
self._take_profit = self.Param("TakeProfit", 500.0) \
.SetDisplay("Take Profit", "Take profit in price units", "Risk")
self._stop_loss = self.Param("StopLoss", 300.0) \
.SetDisplay("Stop Loss", "Stop loss in price units", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Candle type", "General")
self._entry_price = 0.0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(eurusd_v2_0_strategy, self).OnReseted()
self._entry_price = 0.0
def OnStarted2(self, time):
super(eurusd_v2_0_strategy, self).OnStarted2(time)
sma = SimpleMovingAverage()
sma.Length = self._ma_length.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, self._process_candle).Start()
def _process_candle(self, candle, sma_val):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
sma_val = float(sma_val)
tp = float(self._take_profit.Value)
sl = float(self._stop_loss.Value)
if self.Position > 0:
if close - self._entry_price >= tp or self._entry_price - close >= sl:
self.SellMarket()
self._entry_price = 0.0
return
elif self.Position < 0:
if self._entry_price - close >= tp or close - self._entry_price >= sl:
self.BuyMarket()
self._entry_price = 0.0
return
if self.Position != 0:
return
dist = abs(close - sma_val)
if dist < sma_val * 0.002:
return
if close < sma_val:
self.BuyMarket()
self._entry_price = close
elif close > sma_val:
self.SellMarket()
self._entry_price = close
def CreateClone(self):
return eurusd_v2_0_strategy()