GitHub で見る

Scalping 15m EMA MACD RSI ATR

Scalping strategy combining a 50-period EMA trend filter, MACD histogram momentum and RSI levels. Risk management uses ATR-based stop loss and take profit.

The strategy buys when price is above the EMA, the MACD histogram is positive and RSI sits between 50 and the overbought level. Shorts occur when price is below the EMA, the histogram is negative and RSI is between the oversold level and 50. Stops and targets trail by ATR multiples from the close.

Details

  • Entry Criteria: Price relative to EMA, MACD histogram sign, RSI level.
  • Long/Short: Both directions.
  • Exit Criteria: ATR-based stop loss or take profit.
  • Stops: Yes.
  • Default Values:
    • EmaPeriod = 50
    • MacdFast = 12
    • MacdSlow = 26
    • MacdSignal = 9
    • RsiPeriod = 14
    • RsiOverbought = 70
    • RsiOversold = 30
    • AtrPeriod = 14
    • SlAtrMultiplier = 1m
    • TpAtrMultiplier = 2m
    • CandleType = TimeSpan.FromMinutes(15)
  • Filters:
    • Category: Scalping
    • Direction: Both
    • Indicators: EMA, MACD, RSI, ATR
    • Stops: Yes
    • Complexity: Basic
    • Timeframe: Intraday (15m)
    • Seasonality: No
    • Neural Networks: No
    • Divergence: No
    • Risk Level: Medium
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>
/// Scalping 15min EMA MACD RSI ATR strategy using EMA crossover.
/// </summary>
public class Scalping15minEmaMacdRsiAtrStrategy : Strategy
{
	private readonly StrategyParam<int> _slowLength;
	private readonly StrategyParam<DataType> _candleType;

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

	public Scalping15minEmaMacdRsiAtrStrategy()
	{
		_slowLength = Param(nameof(SlowLength), 40)
			.SetGreaterThanZero()
			.SetDisplay("Slow Length", "Slow EMA period", "General");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle type", "General");
	}

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

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		var fast = new ExponentialMovingAverage { Length = 14 };
		var slow = new ExponentialMovingAverage { Length = SlowLength };
		var prevF = 0m; var prevS = 0m; var init = false;
		var lastSignal = DateTimeOffset.MinValue;
		var cooldown = TimeSpan.FromMinutes(360);
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, (candle, f, s) =>
		{
			if (candle.State != CandleStates.Finished) return;
			if (!fast.IsFormed || !slow.IsFormed) return;
			if (!init) { prevF = f; prevS = s; init = true; return; }
			if (candle.OpenTime - lastSignal >= cooldown)
			{
				if (prevF <= prevS && f > s && Position <= 0) { BuyMarket(); lastSignal = candle.OpenTime; }
				else if (prevF >= prevS && f < s && Position >= 0) { SellMarket(); lastSignal = candle.OpenTime; }
			}
			prevF = f; prevS = s;
		}).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
	}
}