Distance-to-Demand-Vector-Strategie
Strategie basierend auf dem Distance-to-Demand-Vector-Indikator. Sie vergleicht die Abstände zu den Long- und Short-Nachfragevektoren und handelt bei deren Kreuzung.
Details
- Einstiegskriterien:
- Long: Abstand zum Long-Vektor > Abstand zum Short-Vektor
- Short: Abstand zum Long-Vektor < Abstand zum Short-Vektor
- Long/Short: Beide
- Ausstiegskriterien:
- Entgegengesetztes Signal
- Stops: Keine
- Standardwerte:
Length= 100CandleType= TimeSpan.FromMinutes(1).TimeFrame()
- Filter:
- Kategorie: Trend
- Richtung: Beide
- Indikatoren: Highest, Lowest
- Stops: Nein
- Komplexität: Grundlegend
- Zeitrahmen: Kurzfristig
- Saisonalität: Nein
- Neuronale Netze: Nein
- Divergenz: Nein
- Risikolevel: Mittel
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>
/// Distance to demand vector strategy.
/// The long vector is the lowest low and the short vector the highest high of the last Length candles.
/// When the distance from the close to the long vector rises above the distance to the short vector the strategy goes long,
/// and when it falls below it goes short, reversing an opposite position.
/// </summary>
public class DistanceToDemandVectorStrategy : Strategy
{
private readonly StrategyParam<int> _length;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevDiff;
/// <summary>
/// Candles that define the demand vectors.
/// </summary>
public int Length
{
get => _length.Value;
set => _length.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public DistanceToDemandVectorStrategy()
{
_length = Param(nameof(Length), 100)
.SetGreaterThanZero()
.SetDisplay("Length", "Candles that define the demand vectors", "Indicators");
_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();
_prevDiff = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevDiff = null;
var highest = new Highest { Length = Length };
var lowest = new Lowest { Length = Length };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(highest, lowest, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, highest);
DrawIndicator(area, lowest);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue highestValue, IIndicatorValue lowestValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!highestValue.IsFormed || !lowestValue.IsFormed)
return;
var close = candle.ClosePrice;
var distanceToLong = close - lowestValue.GetValue<decimal>();
var distanceToShort = highestValue.GetValue<decimal>() - close;
var diff = distanceToLong - distanceToShort;
var prev = _prevDiff;
_prevDiff = diff;
if (prev is not decimal prevDiff)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (prevDiff <= 0m && diff > 0m && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (prevDiff >= 0m && diff < 0m && 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, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class distance_to_demand_vector_strategy(Strategy):
"""
Distance to demand vector strategy.
The long vector is the lowest low and the short vector the highest high of the last Length candles.
When the distance from the close to the long vector rises above the distance to the short vector the strategy goes long,
and when it falls below it goes short, reversing an opposite position.
"""
def __init__(self):
super(distance_to_demand_vector_strategy, self).__init__()
self._length = self.Param("Length", 100) \
.SetGreaterThanZero() \
.SetDisplay("Length", "Candles that define the demand vectors", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._prev_diff = None
@property
def candle_type(self):
return self._candle_type.Value
def GetWorkingSecurities(self):
return [(self.Security, self.candle_type)]
def OnReseted(self):
super(distance_to_demand_vector_strategy, self).OnReseted()
self._prev_diff = None
def OnStarted2(self, time):
super(distance_to_demand_vector_strategy, self).OnStarted2(time)
self._prev_diff = None
highest = Highest()
highest.Length = self._length.Value
lowest = Lowest()
lowest.Length = self._length.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(highest, lowest, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, highest)
self.DrawIndicator(area, lowest)
self.DrawOwnTrades(area)
def _process_candle(self, candle, highest_value, lowest_value):
if candle.State != CandleStates.Finished:
return
if not highest_value.IsFormed or not lowest_value.IsFormed:
return
close = candle.ClosePrice
distance_to_long = close - lowest_value.GetValue[Decimal](None)
distance_to_short = highest_value.GetValue[Decimal](None) - close
diff = distance_to_long - distance_to_short
prev = self._prev_diff
self._prev_diff = diff
if prev is None:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
zero = Decimal(0)
if prev <= zero and diff > zero and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif prev >= zero and diff < zero and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
def CreateClone(self):
return distance_to_demand_vector_strategy()