GitHub で見る

コイン投げ Martingale 戦略

概要

コイン投げ戦略は、エントリーが疑似ランダムなコイン投げによって決定される MetaTrader のオリジナル EA をエミュレートします。一度に開けるポジションは 1 つだけです。完成した各ローソク足が決定ポイントとして機能します:前回の取引がフラットな場合、戦略はコインを投げて計算された取引数量を使用してロングまたはショートポジションをすぐに開きます。すべての取引はストップロスとテイクプロフィットレベルで保護されており、オプションのトレーリングストップがポジションに有利な方向に市場が動くにつれてリスクを絞ることができます。

Martingale スタイルのポジションサイジングモデルが実装されています。前のポジションがストップされた場合、次の取引は設定可能な乗数によってサイズを増加させます。成功した取引はボリュームをベースサイズにリセットします。ユーザー定義の最大ボリュームが取引サイズの無制御な成長を防ぎます。

取引ルール

  1. 完成した各ローソク足で、戦略は現在のポジションを評価します。
  2. ポジションが開いていない場合、疑似乱数がロングまたはショートの方向を選択します。両サイドは等確率で許可されています。
  3. 前回の取引がストップロスで終わった場合を除き、各新しい取引はベースボリュームを使用します。その場合、ボリュームは最大ボリューム制限を尊重しながら Martingale 係数で乗算されます。
  4. 保護ストップロスとテイクプロフィット価格が各ポジションに付属します。終値がこれらの閾値に達すると、ポジションは成行注文で決済されます。
  5. トレーリングストップは有利な動きを監視します。利益がトレーリング距離プラスステップを超えると、利益を確保するためにストップレベルが価格方向に移動します。

パラメーター

  • Stop Loss – エントリー価格からストップロスを計算するために使用される価格ステップ単位の距離。
  • Take Profit – テイクプロフィットのためにエントリー価格に追加される価格ステップ単位の距離。
  • Trailing Stop – トレーリングストップメカニズムを起動する利益距離。トレーリングを無効にするにはゼロに設定。
  • Trailing Step – トレーリングストップが再び移動される前に必要な最小追加利益。
  • Base Volume – Martingale サイクルの最初の取引のボリューム。
  • Martingale Mult – 次の注文サイズを決定するために最後にストップされたボリュームに適用される乗数。
  • Max Volume – 注文サイズのハードキャップ。超過すると取引はスキップされ、警告がログに記録されます。
  • Candle Type – コイン投げとリスク管理チェックが実行されるタイミングを定義するローソク足シリーズ。

注意事項

  • 戦略はオリジナルの EA の動作を模倣するために、エントリーとエグジットの両方に成行注文を使用します。
  • トレーリングストップの計算は商品の価格ステップに依存します。価格ステップが利用できない場合、代わりに生のポイント値が使用されます。
  • 乱数は同時実行で同一のシーケンスを避けるために、現在時刻に基づいた決定論的シードで生成されます。
using System;
using System.Collections.Generic;

using Ecng.Common;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Random coin flip entry with martingale volume management (simplified).
/// Enters randomly using RSI as a tiebreaker, doubles volume after losses.
/// </summary>
public class CoinFlipMartingaleStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiLength;

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public CoinFlipMartingaleStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Candles", "General");

		_rsiLength = Param(nameof(RsiLength), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Length", "RSI period", "Indicators");
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var rsi = new RelativeStrengthIndex { Length = RsiLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, (ICandleMessage candle, decimal rsiValue) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				// Use RSI to decide direction
				if (rsiValue < 35 && Position <= 0)
				{
					BuyMarket();
				}
				else if (rsiValue > 65 && Position >= 0)
				{
					SellMarket();
				}
			})
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawOwnTrades(area);
		}
	}
}