ダイナミック・ティックス・オシレーター・モデル (DTOM)
Dynamic Ticks Oscillator Model は NYSE Down Ticks 指数の変化率を使用します。ROC が標準偏差に基づくダイナミック閾値を下回ったとき、戦略はロングポジションを建てます。ROC が正の閾値を上回ったときにポジションを閉じます。
詳細
- エントリー条件:
ROC < -StdDev * EntryStdDevMultiplier - ロング/ショート: ロングのみ。
- エグジット条件:
ROC > StdDev * ExitStdDevMultiplier - ストップ: いいえ。
- デフォルト値:
RocLength = 5VolatilityLookback = 24EntryStdDevMultiplier = 1.6mExitStdDevMultiplier = 1.4mCandleType = TimeSpan.FromMinutes(5).TimeFrame()
- フィルター:
- カテゴリ: 平均回帰
- 方向: ロングのみ
- インジケーター: RateOfChange, StandardDeviation
- ストップ: いいえ
- 複雑さ: 初心者
- 時間軸: 日足
- 季節性: いいえ
- ニューラルネットワーク: いいえ
- ダイバージェンス: いいえ
- リスクレベル: 中
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>
/// Dynamic Ticks Oscillator Model strategy.
/// Built for the NYSE Down Ticks index as the strategy security. The RocLength rate of change is compared with the standard
/// deviation of that rate over VolatilityLookback candles: a long opens when the ROC drops below -StdDev * EntryStdDevMultiplier
/// and closes when it rises above StdDev * ExitStdDevMultiplier.
/// </summary>
public class DynamicTicksOscillatorModelStrategy : Strategy
{
private readonly StrategyParam<int> _rocLength;
private readonly StrategyParam<int> _volatilityLookback;
private readonly StrategyParam<decimal> _entryStdDevMultiplier;
private readonly StrategyParam<decimal> _exitStdDevMultiplier;
private readonly StrategyParam<DataType> _candleType;
private StandardDeviation _rocStdDev;
/// <summary>
/// Rate of change length.
/// </summary>
public int RocLength
{
get => _rocLength.Value;
set => _rocLength.Value = value;
}
/// <summary>
/// Candles over which the standard deviation of the ROC is measured.
/// </summary>
public int VolatilityLookback
{
get => _volatilityLookback.Value;
set => _volatilityLookback.Value = value;
}
/// <summary>
/// Standard deviation multiplier of the entry threshold.
/// </summary>
public decimal EntryStdDevMultiplier
{
get => _entryStdDevMultiplier.Value;
set => _entryStdDevMultiplier.Value = value;
}
/// <summary>
/// Standard deviation multiplier of the exit threshold.
/// </summary>
public decimal ExitStdDevMultiplier
{
get => _exitStdDevMultiplier.Value;
set => _exitStdDevMultiplier.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public DynamicTicksOscillatorModelStrategy()
{
_rocLength = Param(nameof(RocLength), 5)
.SetGreaterThanZero()
.SetDisplay("ROC Length", "Rate of change length", "Indicators");
_volatilityLookback = Param(nameof(VolatilityLookback), 24)
.SetGreaterThanZero()
.SetDisplay("Volatility Lookback", "Standard deviation length of the ROC", "Indicators");
_entryStdDevMultiplier = Param(nameof(EntryStdDevMultiplier), 1.6m)
.SetGreaterThanZero()
.SetDisplay("Entry StdDev Mult", "Standard deviation multiplier of the entry threshold", "Signals");
_exitStdDevMultiplier = Param(nameof(ExitStdDevMultiplier), 1.4m)
.SetGreaterThanZero()
.SetDisplay("Exit StdDev Mult", "Standard deviation multiplier of the exit threshold", "Signals");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_rocStdDev = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var roc = new RateOfChange { Length = RocLength };
_rocStdDev = new StandardDeviation { Length = VolatilityLookback };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(roc, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
var oscillators = CreateChartArea();
if (oscillators != null)
DrawIndicator(oscillators, roc);
}
}
private void ProcessCandle(ICandleMessage candle, decimal rocValue)
{
if (candle.State != CandleStates.Finished)
return;
// The deviation is measured on the ROC series itself.
var stdValue = _rocStdDev.Process(new DecimalIndicatorValue(_rocStdDev, rocValue, candle.OpenTime) { IsFinal = true });
if (!stdValue.IsFormed)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var std = stdValue.GetValue<decimal>();
if (Position == 0 && rocValue < -std * EntryStdDevMultiplier)
BuyMarket(Volume);
else if (Position > 0 && rocValue > std * ExitStdDevMultiplier)
SellMarket(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
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import RateOfChange, StandardDeviation
from StockSharp.Algo.Strategies import Strategy
from indicator_extensions import *
class dynamic_ticks_oscillator_model_strategy(Strategy):
"""
Dynamic Ticks Oscillator Model strategy.
Built for the NYSE Down Ticks index as the strategy security. The RocLength rate of change is compared with the standard
deviation of that rate over VolatilityLookback candles: a long opens when the ROC drops below -StdDev * EntryStdDevMultiplier
and closes when it rises above StdDev * ExitStdDevMultiplier.
"""
def __init__(self):
super(dynamic_ticks_oscillator_model_strategy, self).__init__()
self._roc_length = self.Param("RocLength", 5).SetGreaterThanZero().SetDisplay("ROC Length", "Rate of change length", "Indicators")
self._volatility_lookback = self.Param("VolatilityLookback", 24).SetGreaterThanZero().SetDisplay("Volatility Lookback", "Standard deviation length of the ROC", "Indicators")
self._entry_std_dev_multiplier = self.Param("EntryStdDevMultiplier", 1.6).SetGreaterThanZero().SetDisplay("Entry StdDev Mult", "Standard deviation multiplier of the entry threshold", "Signals")
self._exit_std_dev_multiplier = self.Param("ExitStdDevMultiplier", 1.4).SetGreaterThanZero().SetDisplay("Exit StdDev Mult", "Standard deviation multiplier of the exit threshold", "Signals")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._roc_std_dev = None
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(dynamic_ticks_oscillator_model_strategy, self).OnReseted()
self._roc_std_dev = None
def OnStarted2(self, time):
super(dynamic_ticks_oscillator_model_strategy, self).OnStarted2(time)
roc = RateOfChange()
roc.Length = self._roc_length.Value
self._roc_std_dev = StandardDeviation()
self._roc_std_dev.Length = self._volatility_lookback.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(roc, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
oscillators = self.CreateChartArea()
if oscillators is not None:
self.DrawIndicator(oscillators, roc)
def _process_candle(self, candle, roc_value):
if candle.State != CandleStates.Finished:
return
# The deviation is measured on the ROC series itself.
std_result = process_float(self._roc_std_dev, roc_value, candle.OpenTime, True)
if not std_result.IsFormed:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
roc = float(roc_value)
std = float(std_result)
if self.Position == 0 and roc < -std * float(self._entry_std_dev_multiplier.Value):
self.BuyMarket(self.Volume)
elif self.Position > 0 and roc > std * float(self._exit_std_dev_multiplier.Value):
self.SellMarket(self.Position)
def CreateClone(self):
return dynamic_ticks_oscillator_model_strategy()