在 GitHub 上查看

颜色 Schaff JCCX 趋势循环策略

该策略是 MQL5 专家 Exp_ColorSchaffJCCXTrendCycle 的 C# 版本, 使用基于 JCCX 算法的 Schaff 趋势循环 (STC) 振荡器。

交易逻辑

  • 在每根完成的蜡烛上计算 Schaff 趋势循环。
  • 当振荡器在高于 High Level 后跌破该水平时,开多单并平空单。
  • 当振荡器在低于 Low Level 后突破该水平时,开空单并平多单。

参数

名称 说明
Fast JCCX 指标中使用的快速 JCCX 周期。
Slow JCCX 指标中使用的慢速 JCCX 周期。
Smoothing JCCX 的 JJMA 平滑因子。
Phase JJMA 相位值。
Cycle Schaff 趋势计算的周期长度。
High Level 振荡器的上触发水平。
Low Level 振荡器的下触发水平。
Open Long 允许开多。
Open Short 允许开空。
Close Long 允许平多。
Close Short 允许平空。

说明

策略使用 StockSharp 的高级 API,并订阅蜡烛数据。只对已完成的蜡烛作出反应。资金管理和风险控制仅用于演示目的。

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>
/// Strategy based on the Schaff Trend Cycle indicator level crossovers.
/// </summary>
public class ColorSchaffJccxTrendCycleStrategy : Strategy
{
	private readonly StrategyParam<decimal> _highLevel;
	private readonly StrategyParam<decimal> _lowLevel;
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _prev;

	public decimal HighLevel { get => _highLevel.Value; set => _highLevel.Value = value; }
	public decimal LowLevel { get => _lowLevel.Value; set => _lowLevel.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public ColorSchaffJccxTrendCycleStrategy()
	{
		_highLevel = Param(nameof(HighLevel), 75m)
			.SetDisplay("High Level", "Upper trigger level", "Signal");

		_lowLevel = Param(nameof(LowLevel), 25m)
			.SetDisplay("Low Level", "Lower trigger level", "Signal");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
	}

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

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var stc = new SchaffTrendCycle();

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(stc, ProcessCandle)
			.Start();

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

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

		if (_prev is null)
		{
			_prev = stc;
			return;
		}

		if (_prev > HighLevel && stc <= HighLevel && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (_prev < LowLevel && stc >= LowLevel && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}

		_prev = stc;
	}
}