Ver no GitHub

Aroon Horn Sign

The Aroon Horn Sign strategy looks for trend reversals using the Aroon indicator. It monitors the Aroon Up and Down lines on higher timeframe candles. When the Aroon Up line crosses above the Aroon Down line and stays above the 50 level, this signals a potential bullish reversal. The strategy closes any short position and opens a new long. Conversely, when Aroon Down dominates above 50, any existing long is closed and a short position is initiated.

The approach uses fixed take-profit and stop-loss levels expressed in price units. These levels are activated through the built-in risk protection module. Because the logic relies only on the Aroon values, it works across different markets and timeframes without additional filters.

Details

  • Data: Price candles.
  • Entry Criteria:
    • Long: Aroon Up > Aroon Down and Aroon Up >= 50.
    • Short: Aroon Down > Aroon Up and Aroon Down >= 50.
  • Exit Criteria:
    • Long positions close when a short entry condition appears.
    • Short positions close when a long entry condition appears.
  • Stops: Fixed stop-loss and take-profit using StartProtection.
  • Default Values:
    • AroonPeriod = 9
    • CandleType = 4‑hour candles
    • TakeProfit = 2000 (price units)
    • StopLoss = 1000 (price units)
  • Filters:
    • Category: Trend reversal
    • Direction: Long and Short
    • Indicators: Aroon
    • Complexity: Simple
    • 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>
/// Aroon Horn Sign trend reversal strategy.
/// Opens long when Aroon Up crosses above Aroon Down above 50.
/// Opens short when the opposite occurs.
/// </summary>
public class AroonHornSignStrategy : Strategy
{
	private readonly StrategyParam<int> _aroonPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private int _prevTrend;

	public int AroonPeriod { get => _aroonPeriod.Value; set => _aroonPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public AroonHornSignStrategy()
	{
		_aroonPeriod = Param(nameof(AroonPeriod), 9)
			.SetDisplay("Aroon Period", "Aroon indicator period", "Indicators");

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

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

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

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

		_prevTrend = 0;

		var aroon = new Aroon { Length = AroonPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.BindEx(aroon, ProcessCandle)
			.Start();

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

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		var value = (IAroonValue)aroonValue;

		var up = value.Up;
		var down = value.Down;

		if (up is null || down is null)
			return;

		var trend = _prevTrend;

		if (up > down && up >= 50m)
			trend = 1;
		else if (down > up && down >= 50m)
			trend = -1;

		if (_prevTrend <= 0 && trend > 0 && Position <= 0)
			BuyMarket();
		else if (_prevTrend >= 0 && trend < 0 && Position >= 0)
			SellMarket();

		_prevTrend = trend;
	}
}