在 GitHub 上查看

BuySell 策略

该策略模拟 MetaTrader 中的 BuySell 专家。它结合移动平均线和平均真实波幅 (ATR) 来识别趋势反转。 当移动平均线转为向上时视为多头趋势,转为向下时视为空头趋势。 只有当上一根K线处于相反状态时才开仓,以确认趋势反转。止损和止盈以价格点表示。

细节

  • 入场逻辑
    • 做多:移动平均线由下降转为上升,且上一根K线为空头。
    • 做空:移动平均线由上升转为下降,且上一根K线为多头。
  • 出场逻辑
    • 多头:移动平均线转为下降或触发止损/止盈。
    • 空头:移动平均线转为上升或触发止损/止盈。
  • 指标:简单移动平均线 (SMA) 和 ATR。
  • 止损:包含价格点形式的止损和止盈。
  • 权限:分别控制多空开仓与平仓。
  • 默认周期:4 小时K线。

参数

名称 默认值 说明
MaPeriod 14 移动平均线周期。
AtrPeriod 60 ATR 周期。
StopLoss 1000 止损点数。
TakeProfit 2000 止盈点数。
AllowLongEntry true 允许开多。
AllowShortEntry true 允许开空。
AllowLongExit true 允许平多。
AllowShortExit true 允许平空。
CandleType H4 计算所用周期。

使用方法

  1. 将策略添加到您的 StockSharp 项目中。
  2. 根据需要调整参数。
  3. 在实盘或回测模式下运行,交易通过 BuyMarketSellMarket 完成。

该方法适用于趋势反转伴随 ATR 波动变化的市场环境。

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>
/// Buy/Sell strategy based on EMA crossover.
/// </summary>
public class BuySellStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public BuySellStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast EMA period", "Indicator");
		_slowPeriod = Param(nameof(SlowPeriod), 28)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow EMA period", "Indicator");
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle type", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
	}

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

		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };

		SubscribeCandles(CandleType)
			.Bind(fast, slow, ProcessCandle)
			.Start();
	}

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

		if (!_hasPrev)
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			_hasPrev = true;
			return;
		}

		var crossUp = _prevFast <= _prevSlow && fastVal > slowVal;
		var crossDown = _prevFast >= _prevSlow && fastVal < slowVal;

		if (crossUp && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (crossDown && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}

		_prevFast = fastVal;
		_prevSlow = slowVal;
	}
}