La estrategia del juego de ruleta recrea el asesor experto similar a un casino de MetaTrader dentro de StockSharp. Trata cada vela terminada como un nuevo giro de la rueda, elige una dirección aleatoria y escala el tamaño de su orden después de las pérdidas usando una progresión de estilo Martingale. La implementación realiza un seguimiento de un bankroll virtual y limita la exposición mediante límites configurables.
Cada ronda comienza aplanando cualquier posición existente, lanzando una moneda virtual para representar el rojo o el negro y enviando una orden de mercado en la dirección seleccionada. Cuando se cierra la siguiente vela, la estrategia comprueba si el cierre se movió a favor de la apuesta. Las ganancias restablecen la apuesta al volumen base, mientras que las pérdidas multiplican la apuesta hasta un límite definido. Una guardia de racha perdedora máxima obliga a reiniciar antes de que la exposición se vuelva extrema. Se pueden insertar velas de enfriamiento opcionales entre rondas para ralentizar el ritmo de las apuestas.
Esta conversión se centra en la gestión del dinero inspirada en los juegos de azar mostrada por el experto original en lugar de en las señales de los indicadores. Demuestra cómo orquestar rondas basadas en tiempo, mantener el estado interno e interactuar con API de alto nivel de StockSharp a través de suscripciones de velas.
Detalles
Criterios de inscripción: Sin filtro técnico. La dirección se selecciona aleatoriamente al final de una vela terminada.
Largo/Corto: Ambas direcciones, elegidas al azar en cada ronda.
Criterios de Salida: La posición se cierra en la siguiente vela terminada, evaluando si el precio cerró por encima o por debajo de la entrada.
Paradas: No hay paradas tradicionales. El riesgo se gestiona con límites de participación y límites de racha.
Valores predeterminados:
BaseVolume = 1 metro
LossMultiplier = 2m
MaxMultiplier = 16m
RoundCooldown = 1
MaxLosingStreak = 5
CandleType = Intervalo de tiempo.DesdeMinutos(1)
Filtros:
Categoría: Gestión del dinero
Dirección: Ambos
Indicadores: Ninguno
Paradas: No
Complejidad: Principiante
Plazo: Corto plazo
Estacionalidad: No
Redes neuronales: No
Divergencia: No
Nivel de riesgo: alto
Notas
Las órdenes de mercado se dimensionan según la apuesta ajustada por el multiplicador y se redondean al paso de volumen del instrumento.
Las ganancias restablecen la apuesta al volumen base; las pérdidas aumentan según el multiplicador hasta alcanzar el multiplicador máximo o el límite de racha de pérdidas.
Las barras de enfriamiento evitan el reingreso inmediato y permiten la sincronización con fuentes de datos más lentas.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Roulette Game strategy: random-like entries based on candle direction with SMA filter.
/// Buys when candle is bullish and close above SMA. Sells when bearish and below SMA.
/// </summary>
public class RouletteGameStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _smaPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int SmaPeriod
{
get => _smaPeriod.Value;
set => _smaPeriod.Value = value;
}
public RouletteGameStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_smaPeriod = Param(nameof(SmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("SMA Period", "SMA period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sma = new SimpleMovingAverage { Length = SmaPeriod };
decimal? prevClose = null;
decimal? prevSma = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(sma, (candle, smaVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
var isBullish = close > candle.OpenPrice;
if (prevClose.HasValue && prevSma.HasValue)
{
var crossUp = prevClose.Value <= prevSma.Value && close > smaVal;
var crossDown = prevClose.Value >= prevSma.Value && close < smaVal;
if (isBullish && crossUp && Position <= 0)
BuyMarket();
else if (!isBullish && crossDown && Position >= 0)
SellMarket();
}
prevClose = close;
prevSma = smaVal;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sma);
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
from indicator_extensions import *
class roulette_game_strategy(Strategy):
def __init__(self):
super(roulette_game_strategy, self).__init__()
self._sma_period = self.Param("SmaPeriod", 20).SetGreaterThanZero().SetDisplay("SMA Period", "SMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30))).SetDisplay("Candle Type", "Candle 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(roulette_game_strategy, self).OnReseted()
self._prev_close = 0
self._prev_sma = 0
self._has_prev = False
def OnStarted2(self, time):
super(roulette_game_strategy, self).OnStarted2(time)
self._prev_close = 0
self._prev_sma = 0
self._has_prev = False
sma = SimpleMovingAverage()
sma.Length = self._sma_period.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(sma, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, sma)
self.DrawOwnTrades(area)
def OnProcess(self, candle, sma_val):
if candle.State != CandleStates.Finished:
return
close = candle.ClosePrice
is_bullish = close > candle.OpenPrice
if self._has_prev:
cross_up = self._prev_close <= self._prev_sma and close > sma_val
cross_down = self._prev_close >= self._prev_sma and close < sma_val
if is_bullish and cross_up and self.Position <= 0:
self.BuyMarket()
elif not is_bullish and cross_down and self.Position >= 0:
self.SellMarket()
self._prev_close = close
self._prev_sma = sma_val
self._has_prev = True
def CreateClone(self):
return roulette_game_strategy()