View on GitHub

Elite eFibo Trader Strategy

Overview

Elite eFibo Trader reproduces the averaging expert advisor that opens a Fibonacci progression of orders while monitoring a moving-average crossover and an optional RSI filter. The StockSharp port keeps the original basket logic: a market entry triggers a stack of pending stop orders spaced by configurable pip distances, and every additional fill increases exposure following the Fibonacci sequence. The strategy automatically flattens the basket once the floating profit reaches a cash target or when the trend filter turns against the current exposure.

Market data

  • Subscribes to a single configurable candle type (default: 15-minute candles).
  • Uses the candle close for indicator values and to evaluate trailing/stop conditions.

Entry logic

  1. Direction is determined either by the moving-average crossover (enabled by default) or by the manual ManualOpenBuy/ManualOpenSell toggles.
  2. When the MA logic is active, a bullish crossover (fast above slow) arms buy baskets and a bearish crossover arms sell baskets. A single signal per candle is enforced.
  3. If the RSI filter is enabled, long baskets require RSI > RsiHigh while short baskets require RSI < RsiLow.
  4. A new ladder is opened only when there are no active orders or positions from the strategy and trading is allowed (TradeAgainAfterProfit).
  5. The first level is opened with a market order, while the remaining levels are submitted as stop orders offset by LevelDistancePips. Volumes follow the Fibonacci sequence and can be adjusted level by level.

Exit logic

  • Each filled level receives an initial stop calculated from StopLossPips and participates in a trailing update when the MA logic detects an adverse crossover.
  • Stops are trailed to close - TrailingStopPips for long baskets and close + TrailingStopPips for short baskets, never moving further away than the current stop.
  • When the price touches a level stop (based on candle high/low), the strategy closes the remaining volume of that level with a market order.
  • If the floating profit of the basket (calculated from instrument PriceStep and StepPrice) reaches MoneyTakeProfit, all positions are closed and pending orders are cancelled.
  • After the basket is flat, any pending stop orders are cancelled automatically. If TradeAgainAfterProfit is false the strategy remains idle until it is reset.

Parameters

Name Description
UseMaLogic Enable or disable the moving-average crossover logic that sets the trade direction.
MaSlowPeriod, MaFastPeriod Periods of the slow and fast SMAs.
TrailingStopPips Pip distance used by the protective trailing stop when the trend filter turns adverse.
UseRsiFilter, RsiPeriod, RsiHigh, RsiLow RSI filter configuration. The filter allows longs above RsiHigh and shorts below RsiLow.
ManualOpenBuy, ManualOpenSell Manual toggles used when MA logic is disabled.
TradeAgainAfterProfit Resume trading after reaching the money take-profit.
LevelDistancePips Distance in pips between consecutive pending orders.
StopLossPips Initial stop offset for every level.
MoneyTakeProfit Cash profit target evaluated on the basket’s open PnL.
Level1VolumeLevel14Volume Volume of each Fibonacci level. Set to zero to disable a level.
CandleType Timeframe/data type used for indicators.

Implementation notes

  • Pip distances are converted from MetaTrader-style points by multiplying the instrument PriceStep by ten when the security has 3 or 5 decimal places. This mirrors the original MyPoint adjustment for 5-digit FX quotes.
  • Each level is tracked independently. The strategy stores entry price, remaining volume, and stop level so partial fills and individual stop-outs are handled in the same way as the MQL expert.
  • Floating profit is computed from PriceStep and StepPrice. Ensure those instrument properties are configured, otherwise the money take-profit will not trigger correctly.
  • StartProtection() is invoked once during startup to enable the built-in safety checks from the StockSharp strategy base class.
  • When no open volume remains, CancelAllPendingOrders() is called automatically, replicating the repeated subCloseAllPending() calls from the original script.

Usage tips

  • Verify the broker settings for PriceStep, StepPrice, VolumeStep, and minimum lot size to ensure Fibonacci volumes translate to valid orders.
  • The strategy relies on candle data; make sure the selected timeframe matches the intended MetaTrader chart period.
  • Consider running the strategy on demo feeds first: averaging systems can accumulate large exposure during adverse trends.
  • Disable UseMaLogic to reproduce the manual bias used in the original EA inputs, or keep it enabled for automatic trend detection.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Elite eFibo Trader: MA crossover with RSI filter and grid averaging.
/// Adds to winning positions on pullbacks using Fibonacci-style scaling.
/// </summary>
public class EliteEfiboTraderStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastLength;
	private readonly StrategyParam<int> _slowLength;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _atrLength;

	private decimal _prevFast;
	private decimal _prevSlow;
	private decimal _entryPrice;
	private int _addCount;

	public EliteEfiboTraderStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(8).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

		_fastLength = Param(nameof(FastLength), 10)
			.SetDisplay("Fast MA", "Fast SMA period.", "Indicators");

		_slowLength = Param(nameof(SlowLength), 30)
			.SetDisplay("Slow MA", "Slow SMA period.", "Indicators");

		_rsiLength = Param(nameof(RsiLength), 14)
			.SetDisplay("RSI Length", "RSI filter period.", "Indicators");

		_atrLength = Param(nameof(AtrLength), 14)
			.SetDisplay("ATR Length", "ATR period.", "Indicators");
	}

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

	public int FastLength
	{
		get => _fastLength.Value;
		set => _fastLength.Value = value;
	}

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

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public int AtrLength
	{
		get => _atrLength.Value;
		set => _atrLength.Value = value;
	}

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

		_prevFast = 0;
		_prevSlow = 0;
		_entryPrice = 0;
		_addCount = 0;
	}

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

		_prevFast = 0;
		_prevSlow = 0;
		_entryPrice = 0;
		_addCount = 0;

		var fast = new SimpleMovingAverage { Length = FastLength };
		var slow = new SimpleMovingAverage { Length = SlowLength };
		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var atr = new AverageTrueRange { Length = AtrLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, rsi, atr, ProcessCandle)
			.Start();

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

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

		if (_prevFast == 0 || _prevSlow == 0 || atrVal <= 0)
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			return;
		}

		var close = candle.ClosePrice;

		// Position management
		if (Position > 0)
		{
			// Take profit or stop
			if (close >= _entryPrice + atrVal * 3m)
			{
				SellMarket();
				_entryPrice = 0;
				_addCount = 0;
			}
			else if (close <= _entryPrice - atrVal * 2m)
			{
				SellMarket();
				_entryPrice = 0;
				_addCount = 0;
			}
			else if (_addCount < 2 && close <= _entryPrice - atrVal * 0.8m && rsiVal < 40)
			{
				// Fibonacci add: buy more on pullback
				_entryPrice = (_entryPrice + close) / 2m;
				_addCount++;
				BuyMarket();
			}
		}
		else if (Position < 0)
		{
			if (close <= _entryPrice - atrVal * 3m)
			{
				BuyMarket();
				_entryPrice = 0;
				_addCount = 0;
			}
			else if (close >= _entryPrice + atrVal * 2m)
			{
				BuyMarket();
				_entryPrice = 0;
				_addCount = 0;
			}
			else if (_addCount < 2 && close >= _entryPrice + atrVal * 0.8m && rsiVal > 60)
			{
				_entryPrice = (_entryPrice + close) / 2m;
				_addCount++;
				SellMarket();
			}
		}

		// Entry: MA crossover with RSI confirmation
		if (Position == 0)
		{
			if (_prevFast <= _prevSlow && fastVal > slowVal && rsiVal > 50)
			{
				_entryPrice = close;
				_addCount = 0;
				BuyMarket();
			}
			else if (_prevFast >= _prevSlow && fastVal < slowVal && rsiVal < 50)
			{
				_entryPrice = close;
				_addCount = 0;
				SellMarket();
			}
		}

		_prevFast = fastVal;
		_prevSlow = slowVal;
	}
}