Esta estrategia reproduce el experto "Hedge Average" de MetaTrader. Compara medias móviles simples de los precios de apertura y cierre en dos períodos de tiempo.
Lógica de trading
Calcular la SMA del precio de apertura y cierre para Period1 y Period2.
Si la media de apertura del período largo está por encima de su media de cierre y la media de apertura del período corto está por debajo de su media de cierre, se abre una posición larga.
Si la media de apertura del período largo está por debajo de su media de cierre y la media de apertura del período corto está por encima de su media de cierre, se abre una posición corta.
El trading solo está permitido entre StartHour y EndHour.
El stop-loss y el take-profit opcionales se establecen en unidades de precio absolutas. El trailing stop mueve el stop protector junto con el precio cuando está habilitado.
Parámetros
Period1 – período para las medias rápidas.
Period2 – período para las medias lentas.
StartHour – hora del día en que el trading se activa.
EndHour – hora del día en que el trading se detiene.
CandleType – marco temporal de velas utilizado para los cálculos.
TakeProfit – distancia del take profit en unidades de precio.
StopLoss – distancia del stop loss en unidades de precio.
UseTrailing – activar trailing stop basado en la distancia del stop-loss.
Notas
La estrategia utiliza un enfoque de posición única y no replica el objetivo de ganancia basado en dinero de la versión MQL original.
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Hedge Average strategy using fast and slow SMA crossover.
/// Adapted from open/close MA comparison to close-price SMA crossover.
/// </summary>
public class HedgeAverageStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevFast;
private decimal? _prevSlow;
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 HedgeAverageStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast SMA period", "Parameters");
_slowPeriod = Param(nameof(SlowPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow SMA period", "Parameters");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevFast = null;
_prevSlow = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, slow, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fast);
DrawIndicator(area, slow);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
{
_prevFast = fastValue;
_prevSlow = slowValue;
return;
}
if (_prevFast is decimal pf && _prevSlow is decimal ps)
{
if (pf <= ps && fastValue > slowValue && Position <= 0)
BuyMarket();
else if (pf >= ps && fastValue < slowValue && Position >= 0)
SellMarket();
}
_prevFast = fastValue;
_prevSlow = slowValue;
}
}
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 hedge_average_strategy(Strategy):
def __init__(self):
super(hedge_average_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 5) \
.SetDisplay("Fast Period", "Fast SMA period", "Parameters")
self._slow_period = self.Param("SlowPeriod", 20) \
.SetDisplay("Slow Period", "Slow SMA period", "Parameters")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._prev_fast = None
self._prev_slow = None
@property
def fast_period(self):
return self._fast_period.Value
@property
def slow_period(self):
return self._slow_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(hedge_average_strategy, self).OnReseted()
self._prev_fast = None
self._prev_slow = None
def OnStarted2(self, time):
super(hedge_average_strategy, self).OnStarted2(time)
fast = ExponentialMovingAverage()
fast.Length = self.fast_period
slow = ExponentialMovingAverage()
slow.Length = self.slow_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast, slow, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
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 self._prev_fast is not None and self._prev_slow is not None:
pf = self._prev_fast
ps = self._prev_slow
if pf <= ps and fast_val > slow_val and self.Position <= 0:
self.BuyMarket()
elif pf >= ps and fast_val < slow_val and self.Position >= 0:
self.SellMarket()
self._prev_fast = fast_val
self._prev_slow = slow_val
def CreateClone(self):
return hedge_average_strategy()