在 GitHub 上查看

SUPERMACBOT by The Guardian Forex TV 策略

概览

SUPERMACBOT by The Guardian Forex TV 策略 通过将 MACD 振荡器、双重简单移动平均线趋势过滤器以及跟踪移动平均线结合在一起,复刻了原始 MetaTrader 智能交易系统的思路。转换后的 StockSharp 版本基于已完成的 K 线进行决策,并在多重多空共振出现时发出市价委托。策略完全基于高级 API:使用蜡烛订阅、指标绑定以及参数化配置,便于跨品种、跨周期复用。

交易逻辑

  1. 数据源:订阅可配置的蜡烛类型(周期),仅在蜡烛收盘后运行逻辑。
  2. 指标计算:每根蜡烛重新计算 MACD(包含快线、慢线、信号线参数)以及两条简单均线,并额外维护一条用于出场确认的跟踪均线。
  3. 开仓条件
    • 多头:MACD 柱线向上穿越阈值、快均线在慢均线上方且收盘价位于跟踪均线上方,同时当前无多头仓位;
    • 空头:MACD 柱线向下穿越负阈值、快均线在慢均线下方且收盘价位于跟踪均线下方,同时当前无空头仓位。
  4. 平仓条件
    • 多头:MACD 柱线跌破零值、快均线下穿慢均线或收盘价跌破跟踪均线;
    • 空头:MACD 柱线上穿零值、快均线上穿慢均线或收盘价上穿跟踪均线。
  5. 风控:策略仅维持单向净头寸,不加仓不锁仓;如需止损或仓位控制,可在 StockSharp 中叠加其他风险规则。

参数

名称 说明 默认值
CandleType 处理的蜡烛类型(时间框架)。 1 分钟
FastMaPeriod 快速简单均线周期。 12
SlowMaPeriod 慢速简单均线周期。 26
MacdFastPeriod MACD 快速 EMA 周期。 12
MacdSlowPeriod MACD 慢速 EMA 周期。 24
MacdSignalPeriod MACD 信号 EMA 周期。 9
HistogramThreshold 开仓所需的 MACD 柱线最小绝对值。 0.0
TrailingPeriod 跟踪简单均线周期。 12

所有参数均通过 StrategyParam<T> 暴露,可在 StockSharp Designer 中直接调优。

使用提示

  • 在加载策略前准备足够的历史数据,确保指标形成后再开始交易;
  • 策略基于净头寸运作,可安全地在多品种组合中复用;
  • 可结合 StockSharp 风险管理与资金管理组件实现更复杂的止损、止盈与分批处理。

与原版 EA 的差异

  • StockSharp 版本采用收盘价驱动的确定性逻辑,而不是 MQL EA 的事件驱动模型;
  • 原 EA 中的资金管理与追踪止损逻辑被简化为基于跟踪均线的平仓规则;
  • 信号阈值通过 MACD 柱线阈值参数体现,用户可根据需要模拟 MQL 中的权重评分系统。

免责声明

量化交易存在风险。请务必在真实资金投入前充分回测与模拟交易。

using System;
using System.Linq;
using System.Collections.Generic;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// SUPERMACBOT strategy converted from the MQL expert by The Guardian Forex TV.
/// </summary>
public class SupermacbotByTheGuardianForexTvStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastMaPeriod;
	private readonly StrategyParam<int> _slowMaPeriod;
	private readonly StrategyParam<int> _macdFastPeriod;
	private readonly StrategyParam<int> _macdSlowPeriod;
	private readonly StrategyParam<int> _macdSignalPeriod;
	private readonly StrategyParam<decimal> _histogramThreshold;
	private readonly StrategyParam<int> _trailingPeriod;

	/// <summary>
	/// Candle type to process.
	/// </summary>
	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	/// <summary>
	/// Fast simple moving average period.
	/// </summary>
	public int FastMaPeriod
	{
		get => _fastMaPeriod.Value;
		set => _fastMaPeriod.Value = value;
	}

	/// <summary>
	/// Slow simple moving average period.
	/// </summary>
	public int SlowMaPeriod
	{
		get => _slowMaPeriod.Value;
		set => _slowMaPeriod.Value = value;
	}

	/// <summary>
	/// Fast EMA period for MACD.
	/// </summary>
	public int MacdFastPeriod
	{
		get => _macdFastPeriod.Value;
		set => _macdFastPeriod.Value = value;
	}

	/// <summary>
	/// Slow EMA period for MACD.
	/// </summary>
	public int MacdSlowPeriod
	{
		get => _macdSlowPeriod.Value;
		set => _macdSlowPeriod.Value = value;
	}

	/// <summary>
	/// Signal EMA period for MACD.
	/// </summary>
	public int MacdSignalPeriod
	{
		get => _macdSignalPeriod.Value;
		set => _macdSignalPeriod.Value = value;
	}

	/// <summary>
	/// Minimal absolute histogram value required for new entries.
	/// </summary>
	public decimal HistogramThreshold
	{
		get => _histogramThreshold.Value;
		set => _histogramThreshold.Value = value;
	}

	/// <summary>
	/// Trailing simple moving average period.
	/// </summary>
	public int TrailingPeriod
	{
		get => _trailingPeriod.Value;
		set => _trailingPeriod.Value = value;
	}

	/// <summary>
	/// Initializes a new instance of <see cref="SupermacbotByTheGuardianForexTvStrategy"/>.
	/// </summary>
	public SupermacbotByTheGuardianForexTvStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to process", "General");

		_fastMaPeriod = Param(nameof(FastMaPeriod), 12)
			.SetGreaterThanZero()
			.SetDisplay("Fast SMA", "Fast SMA period", "Indicators")
			
			.SetOptimize(5, 30, 1);

		_slowMaPeriod = Param(nameof(SlowMaPeriod), 26)
			.SetGreaterThanZero()
			.SetDisplay("Slow SMA", "Slow SMA period", "Indicators")
			
			.SetOptimize(10, 60, 1);

		_macdFastPeriod = Param(nameof(MacdFastPeriod), 12)
			.SetGreaterThanZero()
			.SetDisplay("MACD Fast", "MACD fast EMA period", "Indicators")
			
			.SetOptimize(5, 20, 1);

		_macdSlowPeriod = Param(nameof(MacdSlowPeriod), 24)
			.SetGreaterThanZero()
			.SetDisplay("MACD Slow", "MACD slow EMA period", "Indicators")
			
			.SetOptimize(18, 40, 1);

		_macdSignalPeriod = Param(nameof(MacdSignalPeriod), 9)
			.SetGreaterThanZero()
			.SetDisplay("MACD Signal", "MACD signal EMA period", "Indicators")
			
			.SetOptimize(3, 15, 1);

		_histogramThreshold = Param(nameof(HistogramThreshold), 0m)
			.SetDisplay("Histogram Threshold", "Required MACD histogram magnitude", "Logic");

		_trailingPeriod = Param(nameof(TrailingPeriod), 12)
			.SetGreaterThanZero()
			.SetDisplay("Trailing SMA", "Trailing SMA period", "Logic")
			
			.SetOptimize(6, 30, 1);
	}

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

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

	}

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

		var fastMa = new SimpleMovingAverage { Length = FastMaPeriod };
		var slowMa = new SimpleMovingAverage { Length = SlowMaPeriod };
		var trailingMa = new SimpleMovingAverage { Length = TrailingPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fastMa, slowMa, trailingMa, ProcessCandle)
			.Start();

		StartProtection(
			takeProfit: new Unit(2, UnitTypes.Percent),
			stopLoss: new Unit(1, UnitTypes.Percent));

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

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

		if (Position != 0)
			return;

		var bullishTrend = fastMa > slowMa;
		var bearishTrend = fastMa < slowMa;
		var price = candle.ClosePrice;

		if (bullishTrend && price > trailingMa)
			BuyMarket();
		else if (bearishTrend && price < trailingMa)
			SellMarket();
	}
}