Главная
/
Примеры стратегий
Открыть на GitHub
Стратегия порога UltraFATL
Стратегия использует осциллятор UltraFATL для определения изменения силы тренда. Индикатор выдаёт дискретные значения от 0 до 8. Длинная позиция открывается, когда предыдущий уровень выше 4, а текущий опускается ниже 5, оставаясь положительным. Короткая позиция открывается, когда предыдущий уровень меньше 5, но больше нуля, а текущий поднимается выше 4. По умолчанию применяется таймфрейм H4, но его можно изменить.
Подход предполагает продолжение тренда после отката от экстремальных значений UltraFATL. Позиция переворачивается при появлении противоположного сигнала.
Детали
Критерии входа :
Длинная позиция : UltraFATL(prev) > 4 и UltraFATL(curr) < 5 и UltraFATL(curr) != 0.
Короткая позиция : UltraFATL(prev) < 5 и UltraFATL(prev) != 0 и UltraFATL(curr) > 4.
Длинные/короткие : обе стороны.
Критерии выхода : противоположный сигнал переворачивает позицию.
Стопы : по умолчанию не используются.
Значения по умолчанию :
Candle Type = свечи 4 часа.
Length = 3.
Signal Bar = 1 (используется предыдущий бар).
Фильтры :
Категория: Следование тренду
Направление: Оба
Индикаторы: Один (UltraFATL)
Стопы: Нет
Сложность: Средняя
Таймфрейм: Среднесрочный
Сезонность: Нет
Нейросети: Нет
Дивергенция: Нет
Уровень риска: Средний
using System;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy based on UltraFATL-style threshold signals.
/// </summary>
public class UltraFatlStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _length;
private readonly StrategyParam<int> _signalBar;
private decimal _prevValue;
private bool _isInitialized;
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Smoothing period.
/// </summary>
public int Length
{
get => _length.Value;
set => _length.Value = value;
}
/// <summary>
/// Bar index used for signal calculation.
/// </summary>
public int SignalBar
{
get => _signalBar.Value;
set => _signalBar.Value = value;
}
/// <summary>
/// Initialize the UltraFATL strategy.
/// </summary>
public UltraFatlStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
_length = Param(nameof(Length), 8)
.SetDisplay("Length", "Smoothing period", "UltraFATL")
.SetOptimize(4, 20, 1);
_signalBar = Param(nameof(SignalBar), 1)
.SetDisplay("Signal Bar", "Bar index for signal calculation", "UltraFATL");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevValue = 0m;
_isInitialized = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = Length };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
// Map RSI to the 0..8 discrete UltraFATL-style scale.
var current = Math.Max(0m, Math.Min(8m, rsiValue / 12.5m));
if (!_isInitialized)
{
_prevValue = current;
_isInitialized = true;
return;
}
var previous = _prevValue;
_prevValue = current;
var isBuySignal = previous >= 5m && current < 5m && current > 0m;
var isSellSignal = previous <= 4m && current > 4m;
if (isBuySignal && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (isSellSignal && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class ultra_fatl_strategy(Strategy):
def __init__(self):
super(ultra_fatl_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._length = self.Param("Length", 8) \
.SetDisplay("Length", "Smoothing period", "UltraFATL")
self._signal_bar = self.Param("SignalBar", 1) \
.SetDisplay("Signal Bar", "Bar index for signal calculation", "UltraFATL")
self._prev_value = 0.0
self._is_initialized = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def Length(self):
return self._length.Value
@Length.setter
def Length(self, value):
self._length.Value = value
@property
def SignalBar(self):
return self._signal_bar.Value
@SignalBar.setter
def SignalBar(self, value):
self._signal_bar.Value = value
def OnStarted2(self, time):
super(ultra_fatl_strategy, self).OnStarted2(time)
rsi = RelativeStrengthIndex()
rsi.Length = self.Length
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, self.ProcessCandle).Start()
def ProcessCandle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
rsi = float(rsi_value)
current = max(0.0, min(8.0, rsi / 12.5))
if not self._is_initialized:
self._prev_value = current
self._is_initialized = True
return
previous = self._prev_value
self._prev_value = current
is_buy_signal = previous >= 5.0 and current < 5.0 and current > 0.0
is_sell_signal = previous <= 4.0 and current > 4.0
pos = self.Position
if is_buy_signal and pos <= 0:
self.BuyMarket(self.Volume + abs(pos))
elif is_sell_signal and pos >= 0:
self.SellMarket(self.Volume + abs(pos))
def OnReseted(self):
super(ultra_fatl_strategy, self).OnReseted()
self._prev_value = 0.0
self._is_initialized = False
def CreateClone(self):
return ultra_fatl_strategy()