Стратегия DeMarker Sign
Стратегия использует осциллятор DeMarker для поиска разворотов тренда. На каждой завершённой свече (по умолчанию 4 часа) значение DeMarker сравнивается с настраиваемыми верхним и нижним уровнями. Когда осциллятор поднимается выше нижнего уровня (по умолчанию 0.3), открывается длинная позиция и закрывается короткая. Когда осциллятор опускается ниже верхнего уровня (по умолчанию 0.7), открывается короткая позиция и закрывается длинная. Позиция удерживается до появления противоположного сигнала.
Детали
- Условия входа:
- Лонг: DeMarker пересекает нижний уровень снизу вверх.
- Шорт: DeMarker пересекает верхний уровень сверху вниз.
- Лонг/Шорт: Оба варианта.
- Условия выхода: Противоположный сигнал.
- Стопы: По умолчанию отсутствуют.
- Фильтры: Нет.
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>
/// Strategy based on DeMarker oscillator crossing predefined levels.
/// </summary>
public class DeMarkerSignStrategy : Strategy
{
private readonly StrategyParam<int> _deMarkerPeriod;
private readonly StrategyParam<decimal> _upLevel;
private readonly StrategyParam<decimal> _downLevel;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevDeMarker;
public int DeMarkerPeriod { get => _deMarkerPeriod.Value; set => _deMarkerPeriod.Value = value; }
public decimal UpLevel { get => _upLevel.Value; set => _upLevel.Value = value; }
public decimal DownLevel { get => _downLevel.Value; set => _downLevel.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public DeMarkerSignStrategy()
{
_deMarkerPeriod = Param(nameof(DeMarkerPeriod), 14)
.SetDisplay("DeMarker Period", "Indicator period", "General");
_upLevel = Param(nameof(UpLevel), 0.7m)
.SetDisplay("Upper Level", "Sell when DeMarker falls below", "General");
_downLevel = Param(nameof(DownLevel), 0.3m)
.SetDisplay("Lower Level", "Buy when DeMarker rises above", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevDeMarker = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevDeMarker = null;
var deMarker = new DeMarker { Length = DeMarkerPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(deMarker, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, deMarker);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal deMarker)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (_prevDeMarker is null)
{
_prevDeMarker = deMarker;
return;
}
// DeMarker crosses above lower level -> buy
if (deMarker > DownLevel && _prevDeMarker <= DownLevel && Position <= 0)
BuyMarket();
// DeMarker crosses below upper level -> sell
else if (deMarker < UpLevel && _prevDeMarker >= UpLevel && Position >= 0)
SellMarket();
_prevDeMarker = deMarker;
}
}
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 DeMarker
from StockSharp.Algo.Strategies import Strategy
class de_marker_sign_strategy(Strategy):
def __init__(self):
super(de_marker_sign_strategy, self).__init__()
self._de_marker_period = self.Param("DeMarkerPeriod", 14) \
.SetDisplay("DeMarker Period", "Indicator period", "General")
self._up_level = self.Param("UpLevel", 0.7) \
.SetDisplay("Upper Level", "Sell when DeMarker falls below", "General")
self._down_level = self.Param("DownLevel", 0.3) \
.SetDisplay("Lower Level", "Buy when DeMarker rises above", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe for candles", "General")
self._prev_de_marker = None
@property
def de_marker_period(self):
return self._de_marker_period.Value
@property
def up_level(self):
return self._up_level.Value
@property
def down_level(self):
return self._down_level.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(de_marker_sign_strategy, self).OnReseted()
self._prev_de_marker = None
def OnStarted2(self, time):
super(de_marker_sign_strategy, self).OnStarted2(time)
self._prev_de_marker = None
de_marker = DeMarker()
de_marker.Length = self.de_marker_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(de_marker, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, de_marker)
self.DrawOwnTrades(area)
def process_candle(self, candle, de_marker):
if candle.State != CandleStates.Finished:
return
de_marker = float(de_marker)
if self._prev_de_marker is None:
self._prev_de_marker = de_marker
return
down_lvl = float(self.down_level)
up_lvl = float(self.up_level)
if de_marker > down_lvl and self._prev_de_marker <= down_lvl and self.Position <= 0:
self.BuyMarket()
elif de_marker < up_lvl and self._prev_de_marker >= up_lvl and self.Position >= 0:
self.SellMarket()
self._prev_de_marker = de_marker
def CreateClone(self):
return de_marker_sign_strategy()