Die Roulette-Spielstrategie bildet den Casino-ähnlichen Expertenberater von MetaTrader in StockSharp nach. Es behandelt jede fertige Kerze als eine neue Drehung des Rades, wählt eine zufällige Richtung und skaliert seine Ordergröße nach Verlusten mithilfe einer Progression im Martingale-Stil. Die Implementierung verfolgt eine virtuelle Bankroll und begrenzt das Risiko durch konfigurierbare Obergrenzen.
Jede Runde beginnt mit dem Abflachen einer vorhandenen Position, dem Werfen einer virtuellen Münze, die Rot oder Schwarz darstellt, und dem Senden einer Marktorder in die ausgewählte Richtung. Wenn die nächste Kerze schließt, prüft die Strategie, ob sich der Schlusskurs zugunsten der Wette bewegt hat. Bei Gewinnen wird der Einsatz auf das Basisvolumen zurückgesetzt, bei Verlusten vervielfacht sich der Einsatz bis zu einer definierten Obergrenze. Ein maximaler Pechsträhneschutz erzwingt ein Zurücksetzen, bevor die Gefährdung extrem wird. Zwischen den Runden können optional Abklingkerzen eingefügt werden, um das Wetttempo zu verlangsamen.
Diese Konvertierung konzentriert sich auf das vom ursprünglichen Experten vorgestellte, vom Glücksspiel inspirierte Geldmanagement anstelle von Indikatorsignalen. Es zeigt, wie man zeitbasierte Runden orchestriert, den internen Status aufrechterhält und über Kerzenabonnements mit StockSharps übergeordnetem API interagiert.
Einzelheiten
Eintrittskriterien: Kein technischer Filter. Die Richtung wird am Ende einer fertigen Kerze zufällig ausgewählt.
Lang/Kurz: Beide Richtungen, in jeder Runde zufällig ausgewählt.
Ausstiegskriterien: Die Position wird bei der nächsten abgeschlossenen Kerze geschlossen, wobei bewertet wird, ob der Preis über oder unter dem Einstiegspunkt schloss.
Haltestellen: Keine herkömmlichen Haltestellen. Das Risiko wird durch Einsatzobergrenzen und Streak-Limits gesteuert.
Standardwerte:
BaseVolume = 1m
LossMultiplier = 2m
MaxMultiplier = 16m
RoundCooldown = 1
MaxLosingStreak = 5
CandleType = TimeSpan.FromMinutes(1)
Filter:
Kategorie: Geldmanagement
Richtung: Beide
Indikatoren: Keine
Stopps: Nein
Komplexität: Anfänger
Zeitrahmen: Kurzfristig
Saisonalität: Nein
Neuronale Netze: Nein
Divergenz: Nein
Risikostufe: Hoch
Notizen
Die Größe der Market Orders richtet sich nach dem multiplikatorbereinigten Einsatz und wird auf die Volumenstufe des Instruments gerundet.
Bei Gewinnen wird der Einsatz auf das Basisvolumen zurückgesetzt; Verluste skalieren mit dem Multiplikator, bis der maximale Multiplikator oder das Maximum für die Pechsträhne erreicht ist.
Abklingbalken verhindern den sofortigen Wiedereintritt und ermöglichen die Synchronisierung mit langsameren Datenfeeds.
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()