Inicio
/
Ejemplos de estrategias
Ver en GitHub
Estrategia Macd Volume
Estrategia que combina el MACD (Convergencia/Divergencia de Medias Móviles) con confirmación de volumen. Entra en posiciones cuando la línea MACD cruza la línea de Señal y lo confirma con un aumento de volumen.
Las pruebas indican un retorno anual promedio de aproximadamente 175%. Funciona mejor en el mercado de acciones.
Los cruces del MACD se filtran por un aumento de volumen para confirmar el momentum. Las señales de compra vienen en cruces alcistas con volumen en expansión; las de venta hacen lo contrario.
Los traders de momentum que observan picos de volumen pueden encontrarlo valioso. El riesgo se limita usando un stop de ATR.
Detalles
Criterios de entrada :
Largo: MACD crosses above Signal && Volume > AvgVolume * VolumeMultiplier
Corto: MACD crosses below Signal && Volume > AvgVolume * VolumeMultiplier
Largo/Corto : Ambos
Criterios de salida :
Cruce del MACD en dirección opuesta
Stops : Basado en porcentaje en StopLossPercent
Valores predeterminados :
MacdFast = 12
MacdSlow = 26
MacdSignal = 9
VolumePeriod = 20
VolumeMultiplier = 1.5m
StopLossPercent = 2.0m
CandleType = TimeSpan.FromMinutes(5).TimeFrame()
Filtros :
Categoría: Ruptura
Dirección: Ambos
Indicadores: MACD, Volume
Stops: Sí
Complejidad: Intermedio
Marco temporal: Medio plazo
Estacionalidad: No
Redes neuronales: No
Divergencia: No
Nivel de riesgo: Medio
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>
/// Strategy combining MACD crossover with trend confirmation.
/// Enters on MACD line crossing Signal line.
/// </summary>
public class MacdVolumeStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cooldownBars;
private int _cooldown;
/// <summary>
/// Candle type for strategy calculation.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Cooldown bars between trades.
/// </summary>
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
/// <summary>
/// Strategy constructor.
/// </summary>
public MacdVolumeStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
_cooldownBars = Param(nameof(CooldownBars), 100)
.SetDisplay("Cooldown Bars", "Bars between trades", "General")
.SetRange(5, 500);
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_cooldown = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var macd = new MovingAverageConvergenceDivergenceSignal();
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(macd, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
var macdArea = CreateChartArea();
if (macdArea != null)
DrawIndicator(macdArea, macd);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue macdValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (macdValue is not MovingAverageConvergenceDivergenceSignalValue macdTyped)
return;
if (macdTyped.Macd is not decimal macdLine || macdTyped.Signal is not decimal signalLine)
return;
if (_cooldown > 0)
{
_cooldown--;
return;
}
// Entry: MACD bullish
if (macdLine > signalLine && Position == 0)
{
BuyMarket();
_cooldown = CooldownBars;
}
// Entry: MACD bearish
else if (macdLine < signalLine && Position == 0)
{
SellMarket();
_cooldown = CooldownBars;
}
// Exit on MACD crossover against position
if (Position > 0 && macdLine < signalLine)
{
SellMarket();
_cooldown = CooldownBars;
}
else if (Position < 0 && macdLine > signalLine)
{
BuyMarket();
_cooldown = CooldownBars;
}
}
}
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 MovingAverageConvergenceDivergenceSignal
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
class macd_volume_strategy(Strategy):
"""
Strategy combining MACD crossover with trend confirmation.
Enters on MACD line crossing Signal line.
"""
def __init__(self):
super(macd_volume_strategy, self).__init__()
self._candle_type = self.Param("CandleType", tf(5)) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._cooldown_bars = self.Param("CooldownBars", 100) \
.SetDisplay("Cooldown Bars", "Bars between trades", "General") \
.SetRange(5, 500)
self._cooldown = 0
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
@property
def cooldown_bars(self):
return self._cooldown_bars.Value
def OnStarted2(self, time):
super(macd_volume_strategy, self).OnStarted2(time)
self._cooldown = 0
macd = MovingAverageConvergenceDivergenceSignal()
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(macd, self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
macd_area = self.CreateChartArea()
if macd_area is not None:
self.DrawIndicator(macd_area, macd)
def ProcessCandle(self, candle, macd_value):
if candle.State != CandleStates.Finished:
return
if macd_value.Macd is None or macd_value.Signal is None:
return
macd_line = float(macd_value.Macd)
signal_line = float(macd_value.Signal)
if self._cooldown > 0:
self._cooldown -= 1
return
# Entry: MACD bullish
if macd_line > signal_line and self.Position == 0:
self.BuyMarket()
self._cooldown = self.cooldown_bars
# Entry: MACD bearish
elif macd_line < signal_line and self.Position == 0:
self.SellMarket()
self._cooldown = self.cooldown_bars
# Exit on MACD crossover against position
if self.Position > 0 and macd_line < signal_line:
self.SellMarket()
self._cooldown = self.cooldown_bars
elif self.Position < 0 and macd_line > signal_line:
self.BuyMarket()
self._cooldown = self.cooldown_bars
def OnReseted(self):
super(macd_volume_strategy, self).OnReseted()
self._cooldown = 0
def CreateClone(self):
return macd_volume_strategy()