GitHub で見る

Nova Futures PRO SAFE v6 Strategy

This strategy combines trend, volatility and structure signals. It uses a 200 EMA with ADX to confirm trends, Bollinger Bands versus Keltner Channels to detect squeeze breakouts, and Donchian levels for structure break of highs or lows. Optional higher timeframe filters and a choppiness index avoid trading in low-quality regimes. A cooldown prevents immediate re-entry after a position closes.

Inputs

  • EMA Length — base exponential moving average length
  • DMI Length — period for ADX and directional movement
  • Min ADX — minimum ADX value to consider trend
  • BB Length — Bollinger Bands period
  • BB Mult — Bollinger Bands multiplier
  • KC Length — Keltner Channels period
  • KC Mult — Keltner Channels multiplier
  • Donchian Length — lookback for structure levels
  • Use HTF — enable higher timeframe confirmation
  • HTF Candle — higher timeframe for filters
  • HTF EMA — EMA length on higher timeframe
  • HTF Min ADX — minimum ADX on higher timeframe
  • Use Choppiness — enable choppiness filter
  • Chop Length — choppiness index period
  • Chop Threshold — maximum choppiness allowed
  • Cooldown — bars to wait after an exit
  • Candle Type — main candle timeframe

Notes

Simplified port of the TradingView script "Nova Futures PRO (SAFE v6) — HTF + Choppiness + Cooldown".

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class NovaFuturesProSafeV6Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public NovaFuturesProSafeV6Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame());
	}
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		var fast = new ExponentialMovingAverage { Length = 12 };
		var slow = new ExponentialMovingAverage { Length = 34 };
		var rsi = new RelativeStrengthIndex { Length = 14 };
		var prevF = 0m; var prevS = 0m; var init = false;
		var lastSignal = DateTimeOffset.MinValue;
		var cooldown = TimeSpan.FromMinutes(120);
		var sub = SubscribeCandles(CandleType);
		sub.Bind(fast, slow, rsi, (c, f, s, r) =>
		{
			if (c.State != CandleStates.Finished || !fast.IsFormed || !slow.IsFormed || !rsi.IsFormed) return;
			if (!init) { prevF = f; prevS = s; init = true; return; }
			if (c.OpenTime - lastSignal >= cooldown)
			{
				if (prevF <= prevS && f > s && r > 50 && Position <= 0) { BuyMarket(); lastSignal = c.OpenTime; }
				else if (prevF >= prevS && f < s && r < 50 && Position > 0) { SellMarket(); lastSignal = c.OpenTime; }
			}
			prevF = f; prevS = s;
		}).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, sub); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
	}
}