GitHub で見る

Exp CandlesticksBW Tm戦略

この戦略はStockSharpの高レベルAPI上でMetaTraderエキスパートExp_CandlesticksBW_Tmを再現します。Awesome Oscillator (AO)とAccelerator Oscillator (AC)を組み合わせてロウソク足の色を塗るBill WilliamsのCandlesticks BWインジケーターに依存します。モメンタムの加速と減速はロウソク足の色の遷移によって検出され、オプションの取引セッションフィルターがエントリーを特定のイントラデイ時間に制限します。

動作の仕組み

  1. 設定された時間軸(デフォルトH4)をサブスクライブし、完了した各ロウソク足をAwesome Oscillator (5/34)に送ります。AOシリーズはAcceleratorコンポーネントを生成するために5期間単純移動平均で平滑化されます。
  2. 各ロウソク足は6つの色状態のいずれかに分類されます:2つの強気モメンタム色(AOとACが上昇中)、2つの弱気モメンタム色(AOとACが下落中)、2つのニュートラル色(AO/ACの方向が混合)。ロウソク足のボディ方向が各ペアで暗い色調か明るい色調かを決定します。
  3. 循環バッファーは最近の色インデックスとその開始時間を保存します。SignalBarパラメーターはどの過去バーを評価するかを選択します(デフォルト = 前のロウソク足、つまりオフセット1)。その1つ前のバーがコンテキストとして使用されます。
  4. 古い方のバーが強気モメンタムゾーンに属しており、シグナルバーがそのゾーンを離れるとロングエントリーが有効になります。ショートエントリーは弱気ゾーンでロジックを反映します。出口シグナルは同じモメンタムフィルターを使用して反対方向を決済します。
  5. オプションのセッションフィルター(UseTimeFilter)はStartHour:StartMinuteからEndHour:EndMinuteの間で取引ログを維持します。ウィンドウを出ると開いているポジションが即座に清算され、オーバーナイトエクスポージャーを防ぎます。
  6. ストップロスとテイクプロフィットの保護はStartProtectionを通じて登録され、ポイントベースの距離をインジケーターの価格ステップに変換します。

取引ルール

  • ロングを開く:前のバーの色インデックス< 2(AOとACが上方向に加速中)かつシグナルバーの色インデックス> 1。すでにロングである場合またはロングが無効な場合、ロングエントリーはスキップされます。
  • ショートを開く:前のバーの色インデックス> 3(AOとACが下方向に加速中)かつシグナルバーの色インデックス< 4
  • ロングを閉じる:古い方の色インデックス> 3(弱気加速)かつロング出口が有効な場合にトリガーされます。
  • ショートを閉じる:古い方の色インデックス< 2(強気加速)かつショート出口が有効な場合にトリガーされます。
  • 時間フィルターがアクティブな場合、色ベースの出口シグナルがなくても許可されたセッション外でポジションが強制決済されます。

パラメーター

名前 説明 デフォルト
CandleType AO/AC計算に使用する時間軸。 TimeSpan.FromHours(4).TimeFrame()
Volume 新規エントリーの注文サイズ。 1m
SignalBar シグナルを評価する前にスキップする完了ロウソク足の数(1 = 前のロウソク足)。 1
StopLossPoints インジケーターポイントでの保護ストップ距離。無効にするには0を設定。 1000m
TakeProfitPoints インジケーターポイントでの利益目標距離。無効にするには0を設定。 2000m
EnableLongEntriesEnableShortEntries 各方向のトレードのオープンを許可。 true
EnableLongExitsEnableShortExits 各方向のトレードのクローズを許可。 true
UseTimeFilter 取引セッション制限を有効化。 true
StartHourStartMinuteEndHourEndMinute セッション境界(開始は包括的、時間が同じ場合は終了は排他的)。 0/0/23/59

注意事項

  • 戦略はインジケーターの価格ステップとストップロス・テイクプロフィット距離を自動的に同期します。
  • シグナルは評価されたバーのクローズ時間を使用してタイムスタンプされ、同じバー内での繰り返しトレードが抑制されます。
  • Pythonバージョンは提供されておらず、ソースMQLパッケージ構造に一致しています。
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>
/// Bill Williams Candlesticks BW strategy (simplified).
/// Uses candle body direction with SMA trend filter.
/// </summary>
public class ExpCandlesticksBwTimeStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _smaLength;

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

	public int SmaLength
	{
		get => _smaLength.Value;
		set => _smaLength.Value = value;
	}

	public ExpCandlesticksBwTimeStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candles", "General");

		_smaLength = Param(nameof(SmaLength), 34)
			.SetGreaterThanZero()
			.SetDisplay("SMA Length", "Bill Williams median line proxy", "Indicators");
	}

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

		var sma = new SimpleMovingAverage { Length = SmaLength };

		int bullCount = 0, bearCount = 0;

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

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				var isBullish = candle.ClosePrice > candle.OpenPrice;
				var isBearish = candle.ClosePrice < candle.OpenPrice;

				if (isBullish)
				{
					bullCount++;
					bearCount = 0;
				}
				else if (isBearish)
				{
					bearCount++;
					bullCount = 0;
				}

				// 3 consecutive bullish candles above SMA
				if (bullCount >= 3 && candle.ClosePrice > smaValue && Position <= 0)
				{
					BuyMarket();
					bullCount = 0;
				}
				// 3 consecutive bearish candles below SMA
				else if (bearCount >= 3 && candle.ClosePrice < smaValue && Position >= 0)
				{
					SellMarket();
					bearCount = 0;
				}
			})
			.Start();

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