La estrategia Gonna Scalp es un asesor experto MetaTrader de alta frecuencia trasladado al StockSharp alto nivel API. El sistema busca entradas rápidas de reversión a la media en un gráfico a corto plazo respetando la tendencia dominante del mercado. La confirmación se produce mediante un mecanismo de votación que evalúa el impulso, CCI, ATR, el oscilador estocástico y los filtros MACD antes de permitir una operación. Solo se puede abrir una posición a la vez y cada operación está protegida por distancias fijas de stop-loss y take-profit expresadas en MetaTrader puntos.
Lógica de trading
Preparación de indicadores
Promedios móviles ponderados (WMA) rápidos y lentos calculados sobre el precio típico.
El impulso (período 14) se evalúa en el período de negociación y se convierte en una distancia absoluta desde el valor neutral 100.
Índice de canal de productos básicos (período 20) y rango verdadero promedio (período 12) utilizados como filtros direccionales.
Stochastic oscilador %K/%D (5/3/3) y MACD (26/12/9) procesados en la misma serie de velas.
Señal de votación
Cada indicador aporta un voto para el lado alcista o bajista cuando su lectura actual respalda la tendencia identificada en el código original MetaTrader.
La estrategia recopila tres distancias de impulso recientes y requiere que al menos una de ellas supere un umbral configurable antes de permitir una nueva operación.
Las comprobaciones estructurales adicionales exigen que el mínimo de la barra de hace dos velas permanezca por debajo del máximo de la barra anterior para los largos (condición espejo para los cortos).
Ejecución de orden
Cuando los votos alcistas superan a los bajistas y todos los filtros coinciden, la estrategia abre una posición larga utilizando el tamaño de lote configurado.
Cuando los votos bajistas dominan a los votos alcistas y el filtro de impulso lo aprueba, se abre una posición corta.
Gestión de riesgos
Cada operación abierta va acompañada de distancias fijas de stop-loss y take-profit medidas en MetaTrader puntos y traducidas a incrementos del precio del instrumento.
La lógica protectora cierra la posición en la vela actual una vez que se ha superado cualquiera de los niveles.
Parámetros clave
Nombre
Descripción
Predeterminado
TradeVolume
Tamaño base del pedido en lotes después de la alineación del volumen.
0.01
FastMaPeriod
Longitud del filtro WMA rápido.
1
SlowMaPeriod
Longitud del filtro WMA lento.
5
MomentumPeriod
Número de barras utilizadas por el indicador de impulso.
14
MomentumBuyThreshold
Desviación de impulso absoluta mínima requerida para entradas largas.
0.3
MomentumSellThreshold
Desviación de impulso absoluta mínima requerida para entradas cortas.
0.3
StopLossSteps
Distancia de stop-loss expresada en MetaTrader puntos.
200
TakeProfitSteps
Distancia de obtención de beneficios expresada en MetaTrader puntos.
200
CandleType
Marco de tiempo utilizado para todos los indicadores (el valor predeterminado es velas de 5 minutos).
M5
Notas de uso
Alinear el volumen de la estrategia con el instrumento negociado ajustando TradeVolume; la implementación lo normaliza automáticamente al paso del lote de intercambio.
Los parámetros stop-loss y take-profit operan en MetaTrader puntos. Se convierten a unidades de precio del instrumento según la precisión del instrumento.
Se requieren al menos tres velas completas antes de que la lógica de votación pueda producir señales debido al búfer del historial de impulso.
La estrategia evita deliberadamente la piramidalidad; no se abre una nueva operación hasta que la posición anterior haya sido cerrada mediante gestión de riesgos o una señal opuesta.
Puede conectar la estrategia a gráficos StockSharp para visualizar las series WMA, estocásticas y MACD para la validación de señales.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Gonna Scalp strategy: WMA crossover with CCI momentum filter.
/// Buys when fast WMA above slow WMA and CCI above -100.
/// Sells when fast WMA below slow WMA and CCI below 100.
/// </summary>
public class GonnaScalpStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _cciPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int FastPeriod
{
get => _fastPeriod.Value;
set => _fastPeriod.Value = value;
}
public int SlowPeriod
{
get => _slowPeriod.Value;
set => _slowPeriod.Value = value;
}
public int CciPeriod
{
get => _cciPeriod.Value;
set => _cciPeriod.Value = value;
}
public GonnaScalpStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Fast WMA", "Fast WMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 30)
.SetGreaterThanZero()
.SetDisplay("Slow WMA", "Slow WMA period", "Indicators");
_cciPeriod = Param(nameof(CciPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("CCI Period", "CCI period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new WeightedMovingAverage { Length = FastPeriod };
var slow = new WeightedMovingAverage { Length = SlowPeriod };
var cci = new CommodityChannelIndex { Length = CciPeriod };
decimal? prevFast = null;
decimal? prevSlow = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, slow, cci, (candle, fastVal, slowVal, cciVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (prevFast.HasValue && prevSlow.HasValue)
{
var crossUp = prevFast.Value <= prevSlow.Value && fastVal > slowVal;
var crossDown = prevFast.Value >= prevSlow.Value && fastVal < slowVal;
if (crossUp && cciVal > -100m && Position <= 0)
BuyMarket();
else if (crossDown && cciVal < 100m && Position >= 0)
SellMarket();
}
prevFast = fastVal;
prevSlow = slowVal;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fast);
DrawIndicator(area, slow);
DrawOwnTrades(area);
}
}
}
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 WeightedMovingAverage, CommodityChannelIndex
from StockSharp.Algo.Strategies import Strategy
class gonna_scalp_strategy(Strategy):
def __init__(self):
super(gonna_scalp_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._fast_period = self.Param("FastPeriod", 10) \
.SetGreaterThanZero() \
.SetDisplay("Fast WMA", "Fast WMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 30) \
.SetGreaterThanZero() \
.SetDisplay("Slow WMA", "Slow WMA period", "Indicators")
self._cci_period = self.Param("CciPeriod", 14) \
.SetGreaterThanZero() \
.SetDisplay("CCI Period", "CCI period", "Indicators")
self._prev_fast = None
self._prev_slow = None
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(gonna_scalp_strategy, self).OnReseted()
self._prev_fast = None
self._prev_slow = None
def OnStarted2(self, time):
super(gonna_scalp_strategy, self).OnStarted2(time)
self._fast_ind = WeightedMovingAverage()
self._fast_ind.Length = self._fast_period.Value
self._slow_ind = WeightedMovingAverage()
self._slow_ind.Length = self._slow_period.Value
self._cci_ind = CommodityChannelIndex()
self._cci_ind.Length = self._cci_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._fast_ind, self._slow_ind, self._cci_ind, self._process_candle).Start()
def _process_candle(self, candle, fast_value, slow_value, cci_value):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
fast_val = float(fast_value)
slow_val = float(slow_value)
cci_val = float(cci_value)
if self._prev_fast is not None and self._prev_slow is not None:
cross_up = self._prev_fast <= self._prev_slow and fast_val > slow_val
cross_down = self._prev_fast >= self._prev_slow and fast_val < slow_val
if cross_up and cci_val > -100.0 and self.Position <= 0:
self.BuyMarket()
elif cross_down and cci_val < 100.0 and self.Position >= 0:
self.SellMarket()
self._prev_fast = fast_val
self._prev_slow = slow_val
def CreateClone(self):
return gonna_scalp_strategy()