GitHub で見る

XPeriod Candle System TM Plus 戦略

概要

この戦略は、MetaTraderエキスパートアドバイザー Exp_XPeriodCandleSystem_Tm_Plus のStockSharpポートです。オリジナルのロボットは、カスタムインジケーター XPeriod Candle System に依存しており、ローソク足データを平滑化してボリンジャーバンドのブレイクアウトに応じてバーを色分けします。翻訳版はOHLCシリーズに指数平滑化を適用し、同じ適用価格モードをマッピングし、結果として得られる色の状態からトレードを駆動することでこの動作を再現します。時間ベースの決済と設定可能な保護注文がブレイクアウトロジックを補完します。

トレードロジック

  1. 平滑化ローソク足 – 設定可能な長さの指数移動平均が合成的な始値、高値、安値、終値を構築し、ソースインジケーターを近似します。
  2. 適用価格 – ボリンジャーバンドにデータを入力する前に、12の価格フォーミュラ(終値、始値、中央値、トレンドフォロー変形、Demarkなど)のいずれかを選択できます。
  3. バンド分析 – ボリンジャーバンドインジケーター(長さと偏差が設定可能)が平滑化された価格シリーズを処理します。シグナルが評価される前に完成したバンドが必要です。
  4. 色の状態
    • 上のバンドより上の強気バー → 色 0(上方ブレイクアウト)。
    • 下のバンドより下の弱気バー → 色 4(下方ブレイクアウト)。
    • その他の強気バー → 色 1;その他の弱気バー → 色 3
    • 設定可能なブレイクアウトオフセット(可能な場合はシンボルのティックサイズを使用して価格単位に変換)により誤ったトリガーを回避します。
  5. エントリー – 戦略は SignalBar で定義されたローソク足とその前のローソク足を見ます:
    • 前のバーが強気ブレイクアウト(0)で、シグナルバーがそうでない場合にロングをオープン。
    • 前のバーが弱気ブレイクアウト(4)で、シグナルバーがそうでない場合にショートをオープン。
  6. エグジット
    • 参照バーが弱気(> 2)の場合にロングをクローズ。
    • 参照バーが強気(< 2)の場合にショートをクローズ。
    • オプションの保持タイマー(TimeTradeHoldingMinutes)が指定された分数後にポジションをクローズ。
  7. リスクStartProtection が各トレードにオプションの絶対テイクプロフィットとストップロス距離を展開します。

パラメーター

パラメーター 説明 デフォルト値
OrderVolume 市場エントリーに使用する基本注文サイズ。 0.1
BuyPosOpen / SellPosOpen ロングまたはショートエントリーの有効/無効。 true
BuyPosClose / SellPosClose ロングまたはショートポジション決済を許可。 true
TimeTrade 時間ベースの決済フィルターを有効にする。 true
HoldingMinutes 時間フィルターがポジションをクローズするまでの最大保持時間。 960
CandleType 市場から要求されるローソク足データタイプ(時間軸)。 4時間
Period 平滑化指数移動平均の長さ。 5
BollingerLength ボリンジャー計算ウィンドウ内の平滑化バー数。 20
BandsDeviation バンド幅乗数。 1.001
AppliedPriceMode ボリンジャーインジケーター前に使用される価格変換(終値、始値、中央値、トレンドフォロー、Demarkなど)。 Close
SignalBar シグナル評価に使用されるバーのインデックス(1 = 最後にクローズしたバー)。 1
StopLoss / TakeProfit 保護エンジンが使用する絶対距離(価格単位)。 1000 / 2000
Deviation ボリンジャーバンドの上下に追加される余分なブレイクアウトオフセット。 10

使用上の注意

  • 平滑化ステップは指数移動平均を使用して独自のXPeriod計算を複製します。小さな期間は合成ローソク足を市場価格に近く保ち、大きな期間はトレンド構造を強調します。
  • SignalBar は保存された履歴内(現在のバーの後最大14ポジション)に収まる必要があります。利用可能な履歴より大きい値は自動的にトレードをスキップします。
  • ブレイクアウトオフセットは、証券がティックサイズを公開している場合に PriceStep で乗算されます。これにより、Deviation がポイントで定義されるMetaTraderバージョンと同様の動作が維持されます。
  • StopLossTakeProfit は絶対価格単位で指定します。管理インフラをアクティブに保ちながら保護注文を無効にするにはゼロに設定してください。
  • Python翻訳はまだ提供されていません;このフォルダーにはC#実装のみが含まれています。
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>
/// XPeriod candle system with Bollinger Bands breakout.
/// Buys on close above upper band with bullish candle, sells on close below lower band with bearish candle.
/// </summary>
public class XPeriodCandleSystemTmPlusStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _bbPeriod;
	private readonly StrategyParam<decimal> _bbWidth;

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

	public int BbPeriod
	{
		get => _bbPeriod.Value;
		set => _bbPeriod.Value = value;
	}

	public decimal BbWidth
	{
		get => _bbWidth.Value;
		set => _bbWidth.Value = value;
	}

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

		_bbPeriod = Param(nameof(BbPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("BB Period", "Bollinger Bands period", "Indicators");

		_bbWidth = Param(nameof(BbWidth), 2m)
			.SetGreaterThanZero()
			.SetDisplay("BB Width", "Bollinger Bands width", "Indicators");
	}

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

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

		var bb = new BollingerBands { Length = BbPeriod, Width = BbWidth };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.BindEx(bb, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, IIndicatorValue value)
	{
		if (candle.State != CandleStates.Finished)
			return;

		var bb = (BollingerBandsValue)value;
		if (bb.UpBand is not decimal upper ||
			bb.LowBand is not decimal lower ||
			bb.MovingAverage is not decimal middle)
			return;

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

		// Buy: close above upper band with bullish candle
		if (close > upper && isBullish && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// Sell: close below lower band with bearish candle
		else if (close < lower && isBearish && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}
		// Exit long at middle band
		else if (Position > 0 && close < middle)
		{
			SellMarket();
		}
		// Exit short at middle band
		else if (Position < 0 && close > middle)
		{
			BuyMarket();
		}
	}
}