Стратегия Color XTRIX Histogram
Стратегия торгует по смене направления сглаженного индикатора TRIX (тройная экспоненциальная скользящая средняя по логарифму цены закрытия). Длинная позиция открывается, когда гистограмма TRIX разворачивается вверх после снижения. Короткая позиция открывается при развороте вниз после роста. Позиции переворачиваются при противоположном сигнале. Стоп-лосс и тейк-профит не используются.
Детали
- Условия входа:
- Long:
TRIX растет&&предыдущий TRIX снижался - Short:
TRIX падает&&предыдущий TRIX рос
- Long:
- Длинные/Короткие: Длинные и короткие
- Условия выхода:
- Long:
TRIX разворачивается вниз - Short:
TRIX разворачивается вверх
- Long:
- Стопы: Нет
- Значения по умолчанию:
TRIX Length= 5Smooth Length= 5Momentum Period= 1Candle Type= таймфрейм 4 часа
- Фильтры:
- Категория: Следование тренду
- Направление: Оба
- Индикаторы: TRIX
- Стопы: Нет
- Сложность: Низкая
- Таймфрейм: Среднесрочный
- Сезонность: Нет
- Нейросети: Нет
- Дивергенция: Нет
- Уровень риска: Средний
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Color XTRIX Histogram strategy.
/// Opens or closes positions when smoothed TRIX turns direction.
/// </summary>
public class ColorXtrixHistogramStrategy : Strategy
{
private readonly StrategyParam<int> _trixLength;
private readonly StrategyParam<int> _smoothLength;
private readonly StrategyParam<int> _momentumPeriod;
private readonly StrategyParam<DataType> _candleType;
private TripleExponentialMovingAverage _tripleEma;
private RateOfChange _roc;
private ExponentialMovingAverage _smoother;
private decimal? _prev1;
private decimal? _prev2;
public int TrixLength { get => _trixLength.Value; set => _trixLength.Value = value; }
public int SmoothLength { get => _smoothLength.Value; set => _smoothLength.Value = value; }
public int MomentumPeriod { get => _momentumPeriod.Value; set => _momentumPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ColorXtrixHistogramStrategy()
{
_trixLength = Param(nameof(TrixLength), 5)
.SetDisplay("TRIX Length", "Length for base triple EMA", "Indicators");
_smoothLength = Param(nameof(SmoothLength), 5)
.SetDisplay("Smooth Length", "Length for additional smoothing", "Indicators");
_momentumPeriod = Param(nameof(MomentumPeriod), 1)
.SetDisplay("Momentum Period", "Period for rate of change", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_tripleEma = null;
_roc = null;
_smoother = null;
_prev1 = null;
_prev2 = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prev1 = null;
_prev2 = null;
_tripleEma = new TripleExponentialMovingAverage { Length = TrixLength };
_roc = new RateOfChange { Length = MomentumPeriod };
_smoother = new ExponentialMovingAverage { Length = SmoothLength };
Indicators.Add(_tripleEma);
Indicators.Add(_roc);
Indicators.Add(_smoother);
var warmup = new ExponentialMovingAverage { Length = TrixLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(warmup, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal _warmupVal)
{
if (candle.State != CandleStates.Finished)
return;
var t = candle.ServerTime;
var logClose = (decimal)Math.Log((double)candle.ClosePrice);
var emaResult = _tripleEma.Process(new DecimalIndicatorValue(_tripleEma, logClose, t) { IsFinal = true });
if (!_tripleEma.IsFormed)
return;
var emaVal = emaResult.GetValue<decimal>();
var rocResult = _roc.Process(new DecimalIndicatorValue(_roc, emaVal, t) { IsFinal = true });
if (!_roc.IsFormed)
return;
var rocVal = rocResult.GetValue<decimal>();
var smoothResult = _smoother.Process(new DecimalIndicatorValue(_smoother, rocVal, t) { IsFinal = true });
if (!_smoother.IsFormed)
return;
var trix = smoothResult.GetValue<decimal>();
if (!IsFormedAndOnlineAndAllowTrading())
{
_prev2 = _prev1;
_prev1 = trix;
return;
}
if (_prev1 is null || _prev2 is null)
{
_prev2 = _prev1;
_prev1 = trix;
return;
}
var wasDown = _prev1 < _prev2;
var isUp = trix > _prev1;
var wasUp = _prev1 > _prev2;
var isDown = trix < _prev1;
if (wasDown && isUp && Position <= 0)
BuyMarket();
else if (wasUp && isDown && Position >= 0)
SellMarket();
_prev2 = _prev1;
_prev1 = trix;
}
}
import clr
import math
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 TripleExponentialMovingAverage, RateOfChange, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
from indicator_extensions import *
class color_xtrix_histogram_strategy(Strategy):
def __init__(self):
super(color_xtrix_histogram_strategy, self).__init__()
self._trix_length = self.Param("TrixLength", 5) \
.SetDisplay("TRIX Length", "Length for base triple EMA", "Indicators")
self._smooth_length = self.Param("SmoothLength", 5) \
.SetDisplay("Smooth Length", "Length for additional smoothing", "Indicators")
self._momentum_period = self.Param("MomentumPeriod", 1) \
.SetDisplay("Momentum Period", "Period for rate of change", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._triple_ema = None
self._roc = None
self._smoother = None
self._prev1 = None
self._prev2 = None
@property
def trix_length(self):
return self._trix_length.Value
@property
def smooth_length(self):
return self._smooth_length.Value
@property
def momentum_period(self):
return self._momentum_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(color_xtrix_histogram_strategy, self).OnReseted()
self._triple_ema = None
self._roc = None
self._smoother = None
self._prev1 = None
self._prev2 = None
def OnStarted2(self, time):
super(color_xtrix_histogram_strategy, self).OnStarted2(time)
self._prev1 = None
self._prev2 = None
self._triple_ema = TripleExponentialMovingAverage()
self._triple_ema.Length = self.trix_length
self._roc = RateOfChange()
self._roc.Length = self.momentum_period
self._smoother = ExponentialMovingAverage()
self._smoother.Length = self.smooth_length
self.Indicators.Add(self._triple_ema)
self.Indicators.Add(self._roc)
self.Indicators.Add(self._smoother)
warmup = ExponentialMovingAverage()
warmup.Length = self.trix_length
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(warmup, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def process_candle(self, candle, warmup_val):
if candle.State != CandleStates.Finished:
return
t = candle.ServerTime
close_price = float(candle.ClosePrice)
if close_price <= 0:
return
log_close = math.log(close_price)
ema_result = process_float(self._triple_ema, log_close, t, True)
if not self._triple_ema.IsFormed:
return
ema_val = float(ema_result)
roc_result = process_float(self._roc, ema_val, t, True)
if not self._roc.IsFormed:
return
roc_val = float(roc_result)
smooth_result = process_float(self._smoother, roc_val, t, True)
if not self._smoother.IsFormed:
return
trix = float(smooth_result)
if self._prev1 is None or self._prev2 is None:
self._prev2 = self._prev1
self._prev1 = trix
return
was_down = self._prev1 < self._prev2
is_up = trix > self._prev1
was_up = self._prev1 > self._prev2
is_down = trix < self._prev1
if was_down and is_up and self.Position <= 0:
self.BuyMarket()
elif was_up and is_down and self.Position >= 0:
self.SellMarket()
self._prev2 = self._prev1
self._prev1 = trix
def CreateClone(self):
return color_xtrix_histogram_strategy()