Открыть на GitHub

Стратегия Get Rich or Die Trying GBP

Общее описание

Get Rich or Die Trying GBP — это перенос эксперта MetaTrader 4 «Get Rich or Die Trying GBP» на высокоуровневый API StockSharp. Стратегия отслеживает краткосрочную историю минутных свечей и в строго определённые часы открывает сделку против преобладающего направления последних свечей, рассчитывая на быструю коррекцию в период перекрытия европейской и американской сессий.

Логика работы

  1. По умолчанию используется поток минутных свечей (тип можно изменить параметром CandleType).
  2. Ведётся скользящее окно из Lookback закрытых свечей, где каждая свеча кодируется:
    • +1, если закрылась ниже открытия (медвежья свеча).
    • -1, если закрылась выше открытия (бычья свеча).
    • 0, если свеча нейтральная.
  3. Сумма кодов определяет намерение:
    • Положительная сумма ⇒ преобладают медвежьи свечи ⇒ готовим покупку.
    • Отрицательная сумма ⇒ преобладают бычьи свечи ⇒ готовим продажу.
  4. Сделки разрешены только в первые EntryWindowMinutes минут после наступления одного из двух часов:
    • FirstEntryHour + HourShift (по умолчанию соответствует полуночи по GMT+2).
    • SecondEntryHour + HourShift (по умолчанию 21:00 серверного времени — закрытие Нью-Йорка).
  5. При отсутствии позиции и выполнении всех условий отправляется рыночный ордер с фиксированным объёмом или объёмом, рассчитанным блоком риск-менеджмента.
  6. Во время удержания позиции действует три виртуальных защитных механизма:
    • Частичное взятие прибыли: закрытие при движении PartialTakeProfitPoints шагов цены в прибыльную сторону.
    • Жёсткий стоп-лосс: закрытие при движении StopLossPoints шагов против позиции.
    • Трейлинг-стоп: фиксация прибыли после превышения TrailingStopPoints шагов с учётом максимума (для лонга) или минимума (для шорта) со времени входа.
  7. Дополнительно контролируется финальное значение TakeProfitPoints как запасной уровень тейк-профита.

Параметры

Параметр Значение по умолчанию Описание
TakeProfitPoints 100 Максимальная дистанция тейк-профита (в шагах цены).
PartialTakeProfitPoints 40 Основной тейк-профит (в шагах цены), как в оригинальном советнике.
StopLossPoints 100 Дистанция стоп-лосса (в шагах цены).
TrailingStopPoints 30 Размер трейлинг-стопа (в шагах цены).
FixedVolume 1 Объём сделки (лоты), если риск-менеджмент отключён.
UseMoneyManagement false Включение динамического расчёта объёма.
RiskPercent 10 Процент капитала, которым рискуем в сделке при активном риск-менеджменте.
Lookback 18 Количество свечей в окне подсчёта направлений.
FirstEntryHour 22 Первый час входа (до учёта смещения).
SecondEntryHour 19 Второй час входа (до учёта смещения).
HourShift 2 Часовое смещение для корректировки серверного времени.
EntryWindowMinutes 5 Ширина окна (в минутах) от начала допустимого часа.
CandleType Минутные свечи Тип используемых свечей.

Управление капиталом

При активном UseMoneyManagement объём позиции определяется по формуле риска: доля RiskPercent от текущей стоимости портфеля делится на денежный эквивалент стоп-лосса (StopLossPoints * StepPrice). Полученный объём округляется по LotStep и ограничивается MinVolume инструмента.

Рекомендации по применению

  • Используется серверное время свечей. Отрегулируйте HourShift, чтобы скорректированные часы совпадали с желаемыми торговыми сессиями.
  • Значение Lookback должно быть больше единицы; увеличение окна делает индикатор настроения более плавным, но замедляет реакции.
  • Все защитные условия проверяются на закрытии свечи. Для большей точности можно выбрать более короткий таймфрейм.
  • В версии для StockSharp допускается только одна активная позиция, что упрощает контроль за рисками.

Ограничения

  • Трейлинг-стоп виртуальный: закрытие произойдёт на следующей завершённой свече после срабатывания условия.
  • Расчёт объёма предполагает корректные значения Security.StepPrice, LotStep и MinVolume в торговом инструменте.

Требования

  • Решение AlgoTrading с установленным StockSharp.
  • Исторические и потоковые минутные данные по выбранной GBP-паре.

Источник

  • Оригинальный советник MT4: MQL/7690/Get_rich_or_die_trying_any_gbp.mq4.
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Get Rich GBP Session Reversal strategy - RSI mean reversion with EMA trend filter.
/// Buys when RSI crosses below oversold while price is above EMA (bullish dip).
/// Sells when RSI crosses above overbought while price is below EMA (bearish rally).
/// </summary>
public class GetRichGbpSessionReversalStrategy : Strategy
{
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<decimal> _overbought;
	private readonly StrategyParam<decimal> _oversold;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevRsi;
	private bool _hasPrev;

	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
	public decimal Overbought { get => _overbought.Value; set => _overbought.Value = value; }
	public decimal Oversold { get => _oversold.Value; set => _oversold.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public GetRichGbpSessionReversalStrategy()
	{
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetDisplay("RSI Period", "RSI lookback", "Indicators");

		_emaPeriod = Param(nameof(EmaPeriod), 50)
			.SetDisplay("EMA Period", "EMA trend filter", "Indicators");

		_overbought = Param(nameof(Overbought), 70m)
			.SetDisplay("Overbought", "RSI overbought level", "Levels");

		_oversold = Param(nameof(Oversold), 30m)
			.SetDisplay("Oversold", "RSI oversold level", "Levels");

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

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
	protected override void OnReseted() { base.OnReseted(); _prevRsi = 0m; _hasPrev = false; }

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

		_hasPrev = false;

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var ema = new ExponentialMovingAverage { Length = EmaPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, ema, ProcessCandle)
			.Start();
	}

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

		var close = candle.ClosePrice;

		if (!_hasPrev)
		{
			_prevRsi = rsi;
			_hasPrev = true;
			return;
		}

		// RSI crosses below oversold = buy reversal
		if (_prevRsi >= Oversold && rsi < Oversold && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// RSI crosses above overbought = sell reversal
		else if (_prevRsi <= Overbought && rsi > Overbought && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevRsi = rsi;
	}
}