Стратегия Exp T3 TRIX повторяет одноимённого эксперта MetaTrader 5 и использует трижды сглаженный осциллятор TRIX. Две цепочки Tillson T3 формируют быструю и медленную линию, а торговые решения принимаются по трём режимам, определяющим развороты импульса.
Торговая логика
Расчёт Tillson T3 TRIX
Для быстрого и медленного потоков строится по шесть экспоненциальных средних одинаковой длины, что даёт значения Tillson T3.
Производная T3 (разность между текущим и предыдущим значением, делённая на предыдущее) образует гистограмму TRIX, используемую в качестве сигнала.
Режим Breakdown
Покупка: быстрая TRIX пересекает ноль снизу вверх и включено разрешение на вход в лонг. При разрешённом выходе из шорта сначала закрывается встречная позиция.
Продажа: быстрая TRIX пересекает ноль сверху вниз и разрешён вход в шорт. При разрешённом выходе закрывается лонг.
Только выход: если соответствующий вход запрещён, но гистограмма пересекает ноль, стратегия всё равно закроет противоположную позицию при включённом разрешении.
Режим Twist
Покупка: наклон быстрой TRIX меняется с отрицательного на положительный (после падения начинается рост). Правила закрытия совпадают с режимом Breakdown.
Продажа: наклон меняется с положительного на отрицательный.
Режим CloudTwist
Покупка: быстрая TRIX оказывается выше медленной после того, как на предыдущей свече была ниже.
Продажа: быстрая TRIX уходит ниже медленной после того, как на предыдущей свече находилась выше.
Работа с ордерами
При появлении сигнала на разворот стратегия сначала закрывает противоположную позицию, если разрешены выходы.
Новая заявка выставляется объёмом Volume + |Position|, чтобы при необходимости выполнить разворот одной сделкой.
Включён StartProtection(), использующий защитные механизмы StockSharp.
Параметры
Параметр
Значение по умолчанию
Описание
Fast Length
10
Глубина Tillson T3 для быстрого потока (шестикратная EMA).
Slow Length
18
Глубина Tillson T3 для медленного потока.
Volume Factor
0.7
Коэффициент сглаживания Tillson T3 (0–1).
Mode
Twist
Выбор режима сигналов: Breakdown, Twist или CloudTwist.
Allow Long Entry
true
Разрешить открытие длинных позиций.
Allow Short Entry
true
Разрешить открытие коротких позиций.
Allow Long Exit
true
Разрешить закрытие длинных позиций.
Allow Short Exit
true
Разрешить закрытие коротких позиций.
Candle Type
таймфрейм 4 часа
Таймфрейм свечей для расчётов.
Все параметры реализованы через StrategyParam<T>, отображаются в Designer и готовы к оптимизации.
Рекомендации по использованию
Стратегия обрабатывает только завершённые свечи. Убедитесь, что источник данных предоставляет таймфрейм, указанный в Candle Type.
Для расчёта производных TRIX требуются предыдущие значения, поэтому первые две завершённые свечи используются только для инициализации.
Чтобы повторить поведение оригинального эксперта, отключите соответствующие флаги Allow ..., если нужно запретить направление или выход.
В исходном коде не было стоп-лоссов и тейк-профитов, поэтому они не реализованы и здесь. Добавьте управление риском через модули StockSharp при необходимости.
Детали конверсии
Источник: MQL/2156/exp_t3_trix.mq5 и индикатор t3_trix.mq5.
Порт использует высокоуровневые подписки на свечи и индикаторы StockSharp, сохраняя три режима сигналов.
Tillson T3 воссоздан на основе шести последовательных EMA с регулируемым Volume Factor (по умолчанию 0.7).
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>
/// T3 TRIX strategy using TRIX indicator for momentum signals.
/// Trades on TRIX zero-line crossovers.
/// </summary>
public class ExpT3TrixStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _period;
private decimal? _prevTrix;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int Period
{
get => _period.Value;
set => _period.Value = value;
}
public ExpT3TrixStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_period = Param(nameof(Period), 14)
.SetGreaterThanZero()
.SetDisplay("Period", "TRIX period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevTrix = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevTrix = null;
var trix = new Trix { Length = Period };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(trix, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
var indArea = CreateChartArea();
if (indArea != null)
{
DrawIndicator(indArea, trix);
}
}
private void ProcessCandle(ICandleMessage candle, decimal trixValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
{
_prevTrix = trixValue;
return;
}
if (_prevTrix == null)
{
_prevTrix = trixValue;
return;
}
// TRIX crosses above zero → buy
if (_prevTrix.Value <= 0 && trixValue > 0)
{
if (Position < 0)
BuyMarket();
if (Position <= 0)
BuyMarket();
}
// TRIX crosses below zero → sell
else if (_prevTrix.Value >= 0 && trixValue < 0)
{
if (Position > 0)
SellMarket();
if (Position >= 0)
SellMarket();
}
_prevTrix = trixValue;
}
}
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 Trix
from StockSharp.Algo.Strategies import Strategy
class exp_t3_trix_strategy(Strategy):
def __init__(self):
super(exp_t3_trix_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._period = self.Param("Period", 14) \
.SetDisplay("Period", "TRIX period", "Indicators")
self._prev_trix = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def Period(self):
return self._period.Value
def OnReseted(self):
super(exp_t3_trix_strategy, self).OnReseted()
self._prev_trix = None
def OnStarted2(self, time):
super(exp_t3_trix_strategy, self).OnStarted2(time)
self._prev_trix = None
trix = Trix()
trix.Length = self.Period
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(trix, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
ind_area = self.CreateChartArea()
if ind_area is not None:
self.DrawIndicator(ind_area, trix)
def _on_process(self, candle, trix_value):
if candle.State != CandleStates.Finished:
return
tv = float(trix_value)
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_trix = tv
return
if self._prev_trix is None:
self._prev_trix = tv
return
# TRIX crosses above zero
if self._prev_trix <= 0 and tv > 0:
if self.Position < 0:
self.BuyMarket()
if self.Position <= 0:
self.BuyMarket()
# TRIX crosses below zero
elif self._prev_trix >= 0 and tv < 0:
if self.Position > 0:
self.SellMarket()
if self.Position >= 0:
self.SellMarket()
self._prev_trix = tv
def CreateClone(self):
return exp_t3_trix_strategy()