Esta estrategia recrea la lógica del panel de múltiples indicadores de la herramienta VirtualTradePad de MetaTrader. Rastrea doce señales —
basadas en tendencia, momentum y canales — y solo opera cuando un número configurable de indicadores están de acuerdo. El objetivo es imitar la
matriz de sentimiento visual del panel original y convertirla en una estrategia StockSharp completamente automatizada.
Cómo funciona
Datos: opera un único instrumento en el tipo de vela seleccionado (por defecto 15 minutos).
Indicadores:
Medias móviles simples rápida/lenta para la dirección del cruce.
Cruce de la línea MACD y la señal.
Salidas de sobrecompra/sobreventa del Estocástico %K (niveles 20/80).
Reversiones en los umbrales 30/70 del RSI.
Reversiones en los niveles -100/+100 del CCI.
Reversiones en los niveles -80/-20 del Williams %R.
Ruptura de vuelta al interior del canal de las Bandas de Bollinger.
Ruptura de vuelta al interior del canal del Envelope de media móvil.
Alineación de mandíbula/dientes/labios del Alligator de Bill Williams.
Pendiente de la Media Móvil Adaptativa de Kaufman (ascendente/descendente).
Cruces de la línea cero del Awesome Oscillator.
Cruce de Tenkan-Kijun del Ichimoku.
Cada indicador produce un voto de compra (+1), venta (-1) o neutral (0). Cuando el recuento de votos de compra (o venta) alcanza el
parámetro MinimumConfirmations y supera el lado opuesto, la estrategia abre una posición en esa dirección.
La opción CloseOnOpposite cierra la posición cuando el recuento de votos opuesto alcanza el umbral.
Gestión del riesgo: take profit y stop loss opcionales definidos en pasos del precio del instrumento.
Parámetros
FastMaLength, SlowMaLength – longitudes de las medias móviles para el cruce.
MacdFastLength, MacdSlowLength, MacdSignalLength – configuración del MACD.
StochasticLength, StochasticDLength, StochasticSlowing – configuración del oscilador Estocástico.
RsiLength, CciLength, WilliamsLength – lookbacks de los osciladores.
BollingerLength, BollingerDeviation – Bandas de Bollinger.
EnvelopeLength, EnvelopeDeviation – Envelopes porcentuales alrededor de la SMA.
AlligatorJawLength, AlligatorTeethLength, AlligatorLipsLength – SMMAs del Alligator.
AmaLength, AmaFastPeriod, AmaSlowPeriod – configuración del AMA de Kaufman.
IchimokuTenkanLength, IchimokuKijunLength, IchimokuSenkouLength – líneas del Ichimoku.
AoShortPeriod, AoLongPeriod – ventanas del Awesome Oscillator.
MinimumConfirmations – número de señales alineadas requeridas para entrar.
CloseOnOpposite – salir cuando el recuento de votos opuesto satisface el umbral.
TakeProfitPips, StopLossPips – objetivos de riesgo opcionales en pasos de precio (0 desactiva).
CandleType – marco temporal/tipo de dato para el análisis.
Resumen de la lógica de trading
Actualizar todos los indicadores cuando cierra una vela.
Contar los votos alcistas y bajistas de los indicadores.
Entrar largo/corto cuando los votos alcanzan el umbral de confirmación y superan el lado opuesto.
Opcionalmente cerrar cuando el lado opuesto alcanza el umbral.
Aplicar take profit/stop loss opcionales medidos en pasos de precio.
La estrategia está diseñada para traders discrecionales que disfrutaban del tablero de sentimiento de VirtualTradePad pero desean una
implementación automatizada dentro del framework StockSharp.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class VirtualTradePadSignalStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cciPeriod;
private decimal? _prevCci;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
public VirtualTradePadSignalStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
_cciPeriod = Param(nameof(CciPeriod), 20).SetGreaterThanZero().SetDisplay("CCI Period", "CCI lookback", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevCci = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevCci = null;
var cci = new CommodityChannelIndex { Length = CciPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(cci, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal cciVal)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) { _prevCci = cciVal; return; }
if (_prevCci == null) { _prevCci = cciVal; return; }
if (_prevCci.Value < 0m && cciVal >= 0m && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
else if (_prevCci.Value > 0m && cciVal <= 0m && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
_prevCci = cciVal;
}
}
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 CommodityChannelIndex
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
from indicator_extensions import *
class virtual_trade_pad_signal_strategy(Strategy):
"""CCI crossing zero line for buy/sell signals."""
def __init__(self):
super(virtual_trade_pad_signal_strategy, self).__init__()
self._cci_period = self.Param("CciPeriod", 20).SetGreaterThanZero().SetDisplay("CCI Period", "CCI lookback", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))).SetDisplay("Candle Type", "Timeframe", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(virtual_trade_pad_signal_strategy, self).OnReseted()
self._prev_cci = None
def OnStarted2(self, time):
super(virtual_trade_pad_signal_strategy, self).OnStarted2(time)
self._prev_cci = None
cci = CommodityChannelIndex()
cci.Length = self._cci_period.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(cci, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawOwnTrades(area)
def OnProcess(self, candle, cci_val):
if candle.State != CandleStates.Finished:
return
cv = float(cci_val)
if self._prev_cci is not None:
if self._prev_cci < 0 and cv >= 0 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_cci > 0 and cv <= 0 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_cci = cv
def CreateClone(self):
return virtual_trade_pad_signal_strategy()