GitHub で見る

Bw WiseMan-1 ブレイクアウトストラテジー

このストラテジーは MetaTrader エキスパートアドバイザー Exp_BW-wiseMan-1 の StockSharp ポートです。アリゲーターインジケーターを中心に構築された Bill Williams の WiseMan-1 ブレイクアウトロジックを自動化します。完成したローソク足がアリゲーターの顎から脱出し、同時に最近のスイングの極値をブレイクするたびにシグナルが生成されます。オプションの逆張りモードはシグナルを交換し、ストラテジーが同じブレイクアウトをフェードできるようにします。

コアアイデア

  • 中央価格(高値 + 安値)/ 2 の平滑移動平均を使用して Bill Williams アリゲーターを計算します。
  • 元のインジケーターの視覚化に合わせるために、顎、歯、唇のラインを設定可能なオフセットで前方にシフトします。
  • 現在のローソク足が最後の N 本のバーの高値または安値を超えて拡大する場合にのみブレイクアウトを確認し、動きが最近のノイズより強いことを確認します。
  • 選択した完了ローソク足の数だけ実行を遅延させ、トレーダーが必要に応じて古いシグナルで操作できるようにします。

トレーディングルール

ロング方向

  1. バーはすべての3本のアリゲーターライン(顎、歯、唇)よりで終わる必要があります(高値が顎、歯、唇より低い)。
  2. 終値はローソク足の上半分にある必要があります。つまり、ローソク足の中央値より上。
  3. ローソク足の安値は前の Back バーの安値より厳密に低くなければなりません。
  4. SignalBar の遅延後にシグナルがアクティブになったとき:
    • Close Short が有効な場合、開いているショートをクローズします。
    • Enable Long が有効で現在ポジションが開いていない場合、新しいロングポジションを開きます。

ショート方向

  1. バーはすべての3本のアリゲーターライン(顎、歯、唇)よりで終わる必要があります(安値が顎、歯、唇より大きい)。
  2. 終値はローソク足の下半分にある必要があります。つまり、ローソク足の中央値より下。
  3. ローソク足の高値は前の Back バーの高値より大きくなければなりません。
  4. シグナルがアクティブになったとき:
    • Close Long が有効な場合、既存のロングをクローズします。
    • Enable Short が有効で現在ポジションがない場合、新しいショートポジションを開きます。

逆張りモード

Counter-Trend Modetrue に設定すると、買いと売りのシグナルが交換され、ストラテジーがアリゲーターブレイクアウトの方向に逆らって取引するようになります。

パラメーター

  • Candle Type – ローソク足を構築し、すべてのインジケーター値を計算するために使用する時間軸(デフォルト:1時間)。
  • Counter-Trend Mode – ブレイクアウトロジックを反転して主要トレンドに逆らって取引する(デフォルト:有効、元の EA に一致)。
  • Breakout Depth (Back) – ブレイクアウト検証時に現在の高値/安値と比較する前のバーの数(デフォルト:2)。
  • Jaw Length / Shift – 顎ラインの平滑移動平均の長さと前方変位(デフォルト:13 / 8)。
  • Teeth Length / Shift – 歯ラインの平滑移動平均の長さと前方変位(デフォルト:8 / 5)。
  • Lips Length / Shift – 唇ラインの平滑移動平均の長さと前方変位(デフォルト:5 / 3)。
  • Signal Bar – 検出されたシグナルを実行する前に待つ完了したローソク足の数(デフォルト:1)。
  • Enable Long / Enable Short – 新しいロングまたはショートポジションを開くためのトグル。
  • Close Long / Close Short – シグナルが発動したときに反対のポジションをクローズするためのトグル。

注意事項

  • ストラテジーは成行注文のみに依存し、ハードなストップロスやテイクプロフィットレベルを設定しません。いかなるエグジットも反対のシグナルによって、または関連するクローズトグルを無効にすることによって駆動されます。
  • すべての計算は完成したローソク足で行われます。部分的なイントラバーデータは元の MetaTrader エキスパートと一致するように無視されます。
  • ボリュームは 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;

/// <summary>
/// Bill Williams Wiseman 1 strategy using Alligator-style triple EMA crossover.
/// </summary>
public class BwWiseman1Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _jawPeriod;
	private readonly StrategyParam<int> _teethPeriod;
	private readonly StrategyParam<int> _lipsPeriod;

	private decimal? _prevLips;
	private decimal? _prevTeeth;

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

	public int JawPeriod
	{
		get => _jawPeriod.Value;
		set => _jawPeriod.Value = value;
	}

	public int TeethPeriod
	{
		get => _teethPeriod.Value;
		set => _teethPeriod.Value = value;
	}

	public int LipsPeriod
	{
		get => _lipsPeriod.Value;
		set => _lipsPeriod.Value = value;
	}

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

		_jawPeriod = Param(nameof(JawPeriod), 34)
			.SetGreaterThanZero()
			.SetDisplay("Jaw Period", "Slow EMA (Jaw)", "Indicators");

		_teethPeriod = Param(nameof(TeethPeriod), 13)
			.SetGreaterThanZero()
			.SetDisplay("Teeth Period", "Medium EMA (Teeth)", "Indicators");

		_lipsPeriod = Param(nameof(LipsPeriod), 5)
			.SetGreaterThanZero()
			.SetDisplay("Lips Period", "Fast EMA (Lips)", "Indicators");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevLips = null;
		_prevTeeth = null;
	}

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

		_prevLips = null;
		_prevTeeth = null;

		var jaw = new SmoothedMovingAverage { Length = JawPeriod };
		var teeth = new SmoothedMovingAverage { Length = TeethPeriod };
		var lips = new SmoothedMovingAverage { Length = LipsPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(jaw, teeth, lips, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal jawVal, decimal teethVal, decimal lipsVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!IsFormedAndOnlineAndAllowTrading())
		{
			_prevLips = lipsVal;
			_prevTeeth = teethVal;
			return;
		}

		if (_prevLips == null || _prevTeeth == null)
		{
			_prevLips = lipsVal;
			_prevTeeth = teethVal;
			return;
		}

		// Lips crosses above teeth → buy
		if (_prevLips.Value <= _prevTeeth.Value && lipsVal > teethVal)
		{
			if (Position < 0)
				BuyMarket();
			if (Position <= 0)
				BuyMarket();
		}
		// Lips crosses below teeth → sell
		else if (_prevLips.Value >= _prevTeeth.Value && lipsVal < teethVal)
		{
			if (Position > 0)
				SellMarket();
			if (Position >= 0)
				SellMarket();
		}

		_prevLips = lipsVal;
		_prevTeeth = teethVal;
	}
}