GitHub で見る

CCIT3 ゼロクロス戦略

概要

CCIT3 ゼロクロス戦略は、CCIT3 オシレーターのゼロライン反転を取引する、MetaTrader 5 エキスパートアドバイザーの StockSharp ポートです。このインジケーターは、Tillson T3 スムージング チェーンを商品チャネル インデックス (CCI) に適用することによって構築されます。平滑化されたオシレーターのスイッチがサインするたびに、ストラテジーはフリップの方向に新しいポジションをオープンするか、設定されている場合は現在のポジションをクローズして反転します。

取引ロジック

  • 選択した適用価格と期間を使用して CCI を計算します。
  • Tillson T3 パイプラインを使用してオシレーターを平滑化します。次の 2 つの計算モードが提供されます。
    • シンプル – オリジナルの再計算 MetaTrader インジケーターと同様に動作する永続的な 6 段階のスムージング。
    • NoRecalc – 最新のバーに対してのみ T3 多項式を評価し、軽量の「再計算なし」バージョンをソース コードから再作成します。
  • CCIT3 値がプラスからマイナスにクロスすると、ロングポジションをオープンします (または、Trade Overturn が有効な場合はショートポジションを反転します)。
  • CCIT3 値がマイナスからプラスにクロスすると、ショート ポジションをオープンします (または、Trade Overturn が有効な場合はロング ポジションを反転します)。
  • オプションのテイクプロフィット、ストップロス、トレーリングストップレベルは、StockSharp の StartProtection ヘルパーを通じて管理されます。

指標と計算

  • 商品チャネル指数 (CCI) – 設定可能な適用価格 (終値、始値、高値、安値、中央値、標準値、加重値) および期間に基づいて実行されます。
  • Tillson T3 スムージング – B ボリューム係数を使用した MQL5 インジケーターとまったく同じように実装されます。シンプル モードはバー全体でステートフルな EMA チェーンを維持しますが、NoRecalc は最新の生の CCI 読み取り値から多項式を再計算します。
  • ゼロクロス検出 – 取引は、エキスパートアドバイザーの元の新しいバーチェックを反映して、完成したローソク足で厳密にトリガーされます。

リスクとポジションの管理

  • Take Profit (pts) と Stop Loss (pts) は、商品の PriceStep を使用して絶対価格距離に変換されます。
  • Trailing Stop (pts) は、同じポイント距離で StockSharp のトレーリング エンジンをアクティブにします。
  • Max Drawdown Target は、現在または初期のポートフォリオ値 (volume = OrderVolume * balance / target) を使用して基本注文量を再スケーリングします。固定ロットサイズを維持するには、パラメータをゼロのままにしておきます。
  • Trade Overturn は完全な反転を可能にします。つまり、現在のポジションが最初にクローズされ、次に新しいポジションが反対方向にオープンされます。

パラメーター

名前 デフォルト 説明
Volume 1 ドローダウンスケーリング前の基本注文量。
Take Profit (pts) 1750年 テイクプロフィット距離(ポイント単位)。
Stop Loss (pts) 0 ポイント単位のストップロス距離。
Trailing Stop (pts) 0 トレーリング ストップの距離 (ポイント単位) (0 はトレーリングを無効にします)。
Trade Overturn 偽 反対側の CCIT3 信号の位置を反転します。
CCI Period 285 CCI インジケーターのルックバック期間。
CCI Price 典型的な CCI のフィードに使用される適用価格。
T3 Period 60 ティルソン T3 スムージング長さ。
T3 Volume Factor 0.618 ティルソン T3 B 係数。
Mode シンプル CCIT3 計算モード (Simple または NoRecalc)。
Candle Type 1時間枠 キャンドルのサブスクリプションに使用される時間枠。
Max Drawdown Target 0 適応型ボリュームサイジングのバランス除数 (0 はスケーリングを無効にします)。

実装メモ

  • このストラテジーは、Candle Type で指定された単一のキャンドル ソースをサブスクライブし、完了したキャンドルのみを処理します。
  • すべての出来高値は証券の出来高ステップに合わせられ、VolumeMin/VolumeMax によって制限されます。
  • デフォルトのパラメータは、公開された MT5 設定を複製します。つまり、285 周期 CCI、T3 長さ 60、体積係数 0.618 の CCIT3 シンプル モードです。
  • NoRecalc に切り替えると、正/負のシグナルを生成しながら、生の CCI 記号に即座に反応するという元のインジケーターの動作が維持されます。
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// CCIT3 Zero Cross: EMA crossover with RSI filter and ATR stops.
/// </summary>
public class Ccit3ZeroCrossStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastEmaLength;
	private readonly StrategyParam<int> _slowEmaLength;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _atrLength;

	private decimal _prevFast;
	private decimal _prevSlow;
	private decimal _entryPrice;

	public Ccit3ZeroCrossStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");
		_fastEmaLength = Param(nameof(FastEmaLength), 9)
			.SetDisplay("Fast EMA Length", "Fast EMA period.", "Indicators");
		_slowEmaLength = Param(nameof(SlowEmaLength), 21)
			.SetDisplay("Slow EMA Length", "Slow EMA period.", "Indicators");
		_rsiLength = Param(nameof(RsiLength), 14)
			.SetDisplay("RSI Length", "RSI period.", "Indicators");
		_atrLength = Param(nameof(AtrLength), 14)
			.SetDisplay("ATR Length", "ATR period.", "Indicators");
	}

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastEmaLength { get => _fastEmaLength.Value; set => _fastEmaLength.Value = value; }
	public int SlowEmaLength { get => _slowEmaLength.Value; set => _slowEmaLength.Value = value; }
	public int RsiLength { get => _rsiLength.Value; set => _rsiLength.Value = value; }
	public int AtrLength { get => _atrLength.Value; set => _atrLength.Value = value; }

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevFast = 0; _prevSlow = 0; _entryPrice = 0;
	}

		protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevFast = 0; _prevSlow = 0; _entryPrice = 0;
		var fastEma = new ExponentialMovingAverage { Length = FastEmaLength };
		var slowEma = new ExponentialMovingAverage { Length = SlowEmaLength };
		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var atr = new AverageTrueRange { Length = AtrLength };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fastEma, slowEma, rsi, atr, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fastEma); DrawIndicator(area, slowEma); DrawOwnTrades(area); }
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal slowVal, decimal rsiVal, decimal atrVal)
	{
		if (candle.State != CandleStates.Finished) return;
		if (_prevFast == 0 || _prevSlow == 0 || atrVal <= 0) { _prevFast = fastVal; _prevSlow = slowVal; return; }
		var close = candle.ClosePrice;

		if (Position > 0)
		{
			if ((fastVal < slowVal && _prevFast >= _prevSlow) || close <= _entryPrice - atrVal * 2m) { SellMarket(); _entryPrice = 0; }
		}
		else if (Position < 0)
		{
			if ((fastVal > slowVal && _prevFast <= _prevSlow) || close >= _entryPrice + atrVal * 2m) { BuyMarket(); _entryPrice = 0; }
		}

		if (Position == 0)
		{
			if (fastVal > slowVal && _prevFast <= _prevSlow && rsiVal > 50) { _entryPrice = close; BuyMarket(); }
			else if (fastVal < slowVal && _prevFast >= _prevSlow && rsiVal < 50) { _entryPrice = close; SellMarket(); }
		}
		_prevFast = fastVal; _prevSlow = slowVal;
	}
}