Ähnlichkeitsmaße-Strategie
Eine Beispielstrategie zur Demonstration der Verwendung von Ähnlichkeitsmaßen. Sie berechnet den euklidischen Abstand zwischen dem Preis und seinem einfachen gleitenden Durchschnitt (SMA). Wenn der Abstand unter einen Schwellenwert fällt, kauft die Strategie; wenn er über den Schwellenwert steigt, verkauft sie.
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>
/// Demonstrates a simple similarity measure: Euclidean distance between price and its SMA.
/// </summary>
public class SimilarityMeasuresStrategy : Strategy
{
private readonly StrategyParam<int> _smaLength;
private readonly StrategyParam<decimal> _distanceThreshold;
private readonly StrategyParam<DataType> _candleType;
private decimal? _previousDistance;
public int SmaLength { get => _smaLength.Value; set => _smaLength.Value = value; }
public decimal DistanceThreshold { get => _distanceThreshold.Value; set => _distanceThreshold.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public SimilarityMeasuresStrategy()
{
_smaLength = Param(nameof(SmaLength), 20)
.SetGreaterThanZero()
.SetDisplay("SMA Length", "SMA used as the reference series.", "Similarity");
_distanceThreshold = Param(nameof(DistanceThreshold), 1m)
.SetNotNegative()
.SetDisplay("Distance Threshold", "Euclidean distance boundary.", "Similarity");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle type.", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_previousDistance = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sma = new SimpleMovingAverage { Length = SmaLength };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(sma, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal sma)
{
if (candle.State != CandleStates.Finished)
return;
var distance = Math.Abs(candle.ClosePrice - sma);
if (_previousDistance is decimal previous)
{
if (previous >= DistanceThreshold && distance < DistanceThreshold && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (previous <= DistanceThreshold && distance > DistanceThreshold && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
}
_previousDistance = distance;
}
}
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class similarity_measures_strategy(Strategy):
def __init__(self):
super(similarity_measures_strategy, self).__init__()
self._sma_length = self.Param("SmaLength", 20).SetGreaterThanZero()
self._distance_threshold = self.Param("DistanceThreshold", 1.0).SetNotNegative()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5)))
self._previous_distance = None
@property
def CandleType(self):
return self._candle_type.Value
def GetWorkingSecurities(self):
return [(self.Security, self.CandleType)]
def OnReseted(self):
super(similarity_measures_strategy, self).OnReseted()
self._previous_distance = None
def OnStarted2(self, time):
super(similarity_measures_strategy, self).OnStarted2(time)
sma = SimpleMovingAverage()
sma.Length = int(self._sma_length.Value)
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(sma, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sma)
self.DrawOwnTrades(area)
def _process_candle(self, candle, sma_value):
if candle.State != CandleStates.Finished:
return
distance = abs(float(candle.ClosePrice) - float(sma_value))
threshold = float(self._distance_threshold.Value)
if self._previous_distance is not None:
if self._previous_distance >= threshold and distance < threshold and self.Position <= 0:
self.BuyMarket(self.Volume + Math.Abs(self.Position))
elif self._previous_distance <= threshold and distance > threshold and self.Position >= 0:
self.SellMarket(self.Volume + Math.Abs(self.Position))
self._previous_distance = distance
def CreateClone(self):
return similarity_measures_strategy()