GitHub で見る

ルーレットゲーム

ルーレット ゲーム戦略は、MetaTrader のカジノのようなエキスパート アドバイザーを StockSharp 内に再現します。完成したすべてのローソク足をホイールの新しいスピンとして扱い、ランダムな方向を選択し、損失後に Martingale スタイルの進行を使用して注文サイズを調整します。この実装では、仮想バンクロールを追跡し、構成可能な上限を通じてエクスポージャーを制限します。

すべてのラウンドは、既存のポジションをフラット化し、仮想コインを投げて赤または黒を表し、選択した方向に成行注文を送信することから始まります。次のローソク足が閉じると、戦略はその終値が賭けに有利に動いたかどうかをチェックします。勝利すると賭け金が基本量にリセットされ、負けると賭け金が規定の上限まで増加します。最大連敗ガードにより、危険が極端になる前に強制的にリセットされます。オプションのクールダウン キャンドルをラウンド間に挿入して、賭けのペースを遅くすることができます。

この変換は、インジケーターシグナルではなく、元の専門家によって紹介されたギャンブルにインスピレーションを受けた資金管理に焦点を当てています。時間ベースのラウンドを調整し、内部状態を維持し、キャンドル サブスクリプションを通じて StockSharp の高レベルの API と対話する方法を示します。

詳細

  • エントリー基準: 技術的なフィルターはありません。方向は完成したキャンドルの終わりにランダムに選択されます。
  • ロング/ショート: 両方向、ラウンドごとにランダムに選択されます。
  • 終了基準: ポジションは次の終了ローソク足でクローズされ、価格がエントリーを上回ったか下回ったかを評価します。
  • 停留所: 従来の停留所はありません。リスクはステークキャップとストリーク制限で管理されます。
  • デフォルト値:
    • BaseVolume = 1m
    • LossMultiplier = 2m
    • MaxMultiplier = 16m
    • RoundCooldown = 1
    • MaxLosingStreak = 5
    • CandleType = TimeSpan.FromMinutes(1)
  • フィルター:
    • カテゴリー: お金の管理
    • 方向: 両方
    • インジケーター: なし
    • 停車駅: いいえ
    • 複雑さ: 初心者
    • 期間: 短期
    • 季節性: いいえ
    • ニューラルネットワーク: いいえ
    • 発散: いいえ
    • リスクレベル: 高

注意事項

  • 成行注文は、乗数で調整された賭け金に応じてサイズ設定され、商品の出来高ステップに四捨五入されます。
  • 勝利すると賭け金が基本量にリセットされます。損失は​​、最大乗数または連敗制限に達するまで、乗数によってスケールされます。
  • クールダウン バーにより、即時再入力が防止され、より遅いデータ フィードとの同期が可能になります。
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);
		}
	}
}