Trend Alexcud
Стратегия Trend Alexcud ищет сильное направленное движение, согласуя набор простых скользящих средних и индикатор Accelerator Oscillator на трёх таймфреймах. Она сконвертирована из оригинального эксперта MQL5 "TREND_alexcud v_2".
Система наблюдает три таймфрейма (по умолчанию 15 минут, 1 час, 4 часа). На каждом таймфрейме рассчитываются пять простых скользящих средних (периоды 5, 8, 13, 21, 34) и Accelerator Oscillator. Таймфрейм считается бычьим, если цена закрытия выше всех средних и значение Accelerator положительное. Таймфрейм считается медвежьим, если цена закрытия ниже всех средних и Accelerator отрицательный.
Сделка открывается только при полном совпадении сигналов на всех трёх таймфреймах. Когда все три таймфрейма бычьи — покупка, когда все три медвежьи — продажа. Позиция разворачивается при появлении противоположного сигнала. Защитные ордера управляются встроенной системой StockSharp.
Детали
- Критерии входа
- Long: цена выше всех средних и Accelerator > 0 на каждом таймфрейме.
- Short: цена ниже всех средних и Accelerator < 0 на каждом таймфрейме.
- Направление: обе стороны.
- Критерии выхода: позиция разворачивается при обратном сигнале.
- Стопы: используется встроенная защита (без значений по умолчанию).
- Значения по умолчанию:
- Timeframe1 = 15m, Timeframe2 = 1h, Timeframe3 = 4h
- Периоды МА = 5, 8, 13, 21, 34
- Фильтры:
- Категория: следование тренду
- Направление: обе
- Индикаторы: несколько
- Стопы: да
- Сложность: средняя
- Таймфрейм: мульти-таймфрейм
- Сезонность: нет
- Нейросети: нет
- Дивергенция: нет
- Уровень риска: средний
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Trend strategy based on multiple EMA alignment.
/// Enters long when price is above all 5 EMAs and short when below all 5 EMAs.
/// </summary>
public class TrendAlexcudStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _ma1;
private readonly StrategyParam<int> _ma2;
private readonly StrategyParam<int> _ma3;
private readonly StrategyParam<int> _ma4;
private readonly StrategyParam<int> _ma5;
private int _previousBias;
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
/// <summary>Period of the shortest moving average.</summary>
public int MaPeriod1 { get => _ma1.Value; set => _ma1.Value = value; }
/// <summary>Period of the second moving average.</summary>
public int MaPeriod2 { get => _ma2.Value; set => _ma2.Value = value; }
/// <summary>Period of the third moving average.</summary>
public int MaPeriod3 { get => _ma3.Value; set => _ma3.Value = value; }
/// <summary>Period of the fourth moving average.</summary>
public int MaPeriod4 { get => _ma4.Value; set => _ma4.Value = value; }
/// <summary>Period of the longest moving average.</summary>
public int MaPeriod5 { get => _ma5.Value; set => _ma5.Value = value; }
/// <summary>
/// Constructor.
/// </summary>
public TrendAlexcudStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Primary timeframe", "General");
_ma1 = Param(nameof(MaPeriod1), 5)
.SetGreaterThanZero()
.SetDisplay("MA 1", "Shortest MA period", "Indicators");
_ma2 = Param(nameof(MaPeriod2), 8)
.SetGreaterThanZero()
.SetDisplay("MA 2", "Second MA period", "Indicators");
_ma3 = Param(nameof(MaPeriod3), 13)
.SetGreaterThanZero()
.SetDisplay("MA 3", "Third MA period", "Indicators");
_ma4 = Param(nameof(MaPeriod4), 21)
.SetGreaterThanZero()
.SetDisplay("MA 4", "Fourth MA period", "Indicators");
_ma5 = Param(nameof(MaPeriod5), 34)
.SetGreaterThanZero()
.SetDisplay("MA 5", "Longest MA period", "Indicators");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_previousBias = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema1 = new ExponentialMovingAverage { Length = MaPeriod1 };
var ema2 = new ExponentialMovingAverage { Length = MaPeriod2 };
var ema3 = new ExponentialMovingAverage { Length = MaPeriod3 };
var ema4 = new ExponentialMovingAverage { Length = MaPeriod4 };
var ema5 = new ExponentialMovingAverage { Length = MaPeriod5 };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema1, ema2, ema3, ema4, ema5, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema1);
DrawIndicator(area, ema2);
DrawIndicator(area, ema3);
DrawIndicator(area, ema4);
DrawIndicator(area, ema5);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal v1, decimal v2, decimal v3, decimal v4, decimal v5)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var price = candle.ClosePrice;
var isBull = price > v1 && price > v2 && price > v3 && price > v4 && price > v5;
var isBear = price < v1 && price < v2 && price < v3 && price < v4 && price < v5;
var bias = isBull ? 1 : isBear ? -1 : 0;
if (isBull && _previousBias != 1 && Position <= 0)
{
BuyMarket(Volume + Math.Abs(Position));
}
else if (isBear && _previousBias != -1 && Position >= 0)
{
SellMarket(Volume + Math.Abs(Position));
}
_previousBias = bias;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
from indicator_extensions import *
class trend_alexcud_strategy(Strategy):
"""Multiple EMA alignment: long when price above all 5 EMAs, short when below all."""
def __init__(self):
super(trend_alexcud_strategy, self).__init__()
self._ma1 = self.Param("MaPeriod1", 5).SetGreaterThanZero().SetDisplay("MA 1", "Shortest MA period", "Indicators")
self._ma2 = self.Param("MaPeriod2", 8).SetGreaterThanZero().SetDisplay("MA 2", "Second MA period", "Indicators")
self._ma3 = self.Param("MaPeriod3", 13).SetGreaterThanZero().SetDisplay("MA 3", "Third MA period", "Indicators")
self._ma4 = self.Param("MaPeriod4", 21).SetGreaterThanZero().SetDisplay("MA 4", "Fourth MA period", "Indicators")
self._ma5 = self.Param("MaPeriod5", 34).SetGreaterThanZero().SetDisplay("MA 5", "Longest MA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30))).SetDisplay("Candle Type", "Primary timeframe", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(trend_alexcud_strategy, self).OnReseted()
self._prev_bias = 0
def OnStarted2(self, time):
super(trend_alexcud_strategy, self).OnStarted2(time)
self._prev_bias = 0
ema1 = ExponentialMovingAverage()
ema1.Length = self._ma1.Value
ema2 = ExponentialMovingAverage()
ema2.Length = self._ma2.Value
ema3 = ExponentialMovingAverage()
ema3.Length = self._ma3.Value
ema4 = ExponentialMovingAverage()
ema4.Length = self._ma4.Value
ema5 = ExponentialMovingAverage()
ema5.Length = self._ma5.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(ema1, ema2, ema3, ema4, ema5, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, ema1)
self.DrawIndicator(area, ema5)
self.DrawOwnTrades(area)
def OnProcess(self, candle, v1, v2, v3, v4, v5):
if candle.State != CandleStates.Finished:
return
price = float(candle.ClosePrice)
is_bull = price > v1 and price > v2 and price > v3 and price > v4 and price > v5
is_bear = price < v1 and price < v2 and price < v3 and price < v4 and price < v5
if is_bull and self._prev_bias != 1 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif is_bear and self._prev_bias != -1 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
if is_bull:
self._prev_bias = 1
elif is_bear:
self._prev_bias = -1
else:
self._prev_bias = 0
def CreateClone(self):
return trend_alexcud_strategy()