ダウ理論トレンド戦略
ダウ理論トレンド戦略は、ピボット高値と安値を使用してトレンド方向を決定します。より高い高値とより高い安値が出現した場合にロングエントリーし、より低い高値とより低い安値が形成された場合にショートエントリーします。
詳細
- エントリー条件: より高い高値と安値でロング;より低い高値と安値でショート。
- ロング/ショート: 両方向。
- エグジット条件: 反対のシグナル。
- ストップ: なし。
- デフォルト値:
PivotLookback= 10CandleType= TimeSpan.FromMinutes(1)
- フィルター:
- カテゴリ: トレンドフォロー
- 方向: 両方
- インジケーター: 価格アクション
- ストップ: いいえ
- 複雑さ: 基本
- 時間軸: 任意
- 季節性: いいえ
- ニューラルネットワーク: いいえ
- ダイバージェンス: はい
- リスクレベル: 中
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Dow Theory Trend strategy.
/// A pivot high is a candle whose high is above the highs of the PivotLookback candles on each side, a pivot low mirrors it with
/// lows; a pivot is confirmed PivotLookback candles after it formed. When the last pivot high is above the one before it and the
/// last pivot low is above the one before it, the trend is up and the strategy goes long; lower highs and lower lows go short.
/// The opposite signal reverses the position.
/// </summary>
public class DowTheoryTrendStrategy : Strategy
{
private readonly StrategyParam<int> _pivotLookback;
private readonly StrategyParam<DataType> _candleType;
private readonly List<decimal> _highs = [];
private readonly List<decimal> _lows = [];
private decimal? _lastPivotHigh;
private decimal? _prevPivotHigh;
private decimal? _lastPivotLow;
private decimal? _prevPivotLow;
/// <summary>
/// Candles on each side of a pivot.
/// </summary>
public int PivotLookback
{
get => _pivotLookback.Value;
set => _pivotLookback.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public DowTheoryTrendStrategy()
{
_pivotLookback = Param(nameof(PivotLookback), 10)
.SetGreaterThanZero()
.SetDisplay("Pivot Lookback", "Candles on each side of a pivot", "Pivots");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).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();
ResetState();
}
private void ResetState()
{
_highs.Clear();
_lows.Clear();
_lastPivotHigh = null;
_prevPivotHigh = null;
_lastPivotLow = null;
_prevPivotLow = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
ResetState();
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
var lookback = PivotLookback;
var size = lookback * 2 + 1;
_highs.Add(candle.HighPrice);
_lows.Add(candle.LowPrice);
if (_highs.Count > size)
{
_highs.RemoveAt(0);
_lows.RemoveAt(0);
}
if (_highs.Count < size)
return;
var centerHigh = _highs[lookback];
var centerLow = _lows[lookback];
var isPivotHigh = true;
var isPivotLow = true;
for (var i = 0; i < size; i++)
{
if (i == lookback)
continue;
if (_highs[i] >= centerHigh)
isPivotHigh = false;
if (_lows[i] <= centerLow)
isPivotLow = false;
}
if (isPivotHigh)
{
_prevPivotHigh = _lastPivotHigh;
_lastPivotHigh = centerHigh;
}
if (isPivotLow)
{
_prevPivotLow = _lastPivotLow;
_lastPivotLow = centerLow;
}
if (_lastPivotHigh is not decimal lastHigh || _prevPivotHigh is not decimal prevHigh
|| _lastPivotLow is not decimal lastLow || _prevPivotLow is not decimal prevLow)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var upTrend = lastHigh > prevHigh && lastLow > prevLow;
var downTrend = lastHigh < prevHigh && lastLow < prevLow;
if (upTrend && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (downTrend && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Strategies import Strategy
class dow_theory_trend_strategy(Strategy):
"""
Dow Theory Trend strategy.
A pivot high is a candle whose high is above the highs of the PivotLookback candles on each side, a pivot low mirrors it with
lows; a pivot is confirmed PivotLookback candles after it formed. When the last pivot high is above the one before it and the
last pivot low is above the one before it, the trend is up and the strategy goes long; lower highs and lower lows go short.
The opposite signal reverses the position.
"""
def __init__(self):
super(dow_theory_trend_strategy, self).__init__()
self._pivot_lookback = self.Param("PivotLookback", 10).SetGreaterThanZero().SetDisplay("Pivot Lookback", "Candles on each side of a pivot", "Pivots")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._reset_state()
@property
def candle_type(self):
return self._candle_type.Value
def _reset_state(self):
self._highs = []
self._lows = []
self._last_pivot_high = None
self._prev_pivot_high = None
self._last_pivot_low = None
self._prev_pivot_low = None
def OnReseted(self):
super(dow_theory_trend_strategy, self).OnReseted()
self._reset_state()
def OnStarted2(self, time):
super(dow_theory_trend_strategy, self).OnStarted2(time)
self._reset_state()
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
lookback = self._pivot_lookback.Value
size = lookback * 2 + 1
self._highs.append(candle.HighPrice)
self._lows.append(candle.LowPrice)
if len(self._highs) > size:
self._highs.pop(0)
self._lows.pop(0)
if len(self._highs) < size:
return
center_high = self._highs[lookback]
center_low = self._lows[lookback]
is_pivot_high = True
is_pivot_low = True
for i in range(size):
if i == lookback:
continue
if self._highs[i] >= center_high:
is_pivot_high = False
if self._lows[i] <= center_low:
is_pivot_low = False
if is_pivot_high:
self._prev_pivot_high = self._last_pivot_high
self._last_pivot_high = center_high
if is_pivot_low:
self._prev_pivot_low = self._last_pivot_low
self._last_pivot_low = center_low
if self._last_pivot_high is None or self._prev_pivot_high is None or self._last_pivot_low is None or self._prev_pivot_low is None:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
up_trend = self._last_pivot_high > self._prev_pivot_high and self._last_pivot_low > self._prev_pivot_low
down_trend = self._last_pivot_high < self._prev_pivot_high and self._last_pivot_low < self._prev_pivot_low
if up_trend and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif down_trend and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
def CreateClone(self):
return dow_theory_trend_strategy()