Diese Strategie handelt Ausbrüche, wenn der Schlusskurs sich über kürzliche Extremwerte hinausbewegt.
Sie berechnet die höchsten und niedrigsten Schlusskurse über einen konfigurierbaren Zeitraum.
Ein neuer Aufwärtstrend wird erkannt, wenn der Schlusskurs das jüngste Hoch überschreitet,
während ein Abwärtstrend beginnt, wenn der Schlusskurs unter das jüngste Tief fällt.
Wenn ein neuer Aufwärtstrend erkannt wird, können bestehende Short-Positionen geschlossen und optionale Long-Positionen geöffnet werden.
Umgekehrt ermöglicht ein neuer Abwärtstrend das Schließen von Long-Positionen und optional das Öffnen von Shorts.
Die Strategie verarbeitet nur abgeschlossene Kerzen und verwendet die High-Level-API von StockSharp.
Parameter
Period – Anzahl der Balken zur Bestimmung kürzlicher Extremwerte.
Candle Type – Zeitrahmen der Kerzen.
Open Long – Long-Positionen eröffnen erlauben.
Open Short – Short-Positionen eröffnen erlauben.
Close Long – Long-Positionen schließen erlauben.
Close Short – Short-Positionen schließen erlauben.
Logik
Kerzendaten des ausgewählten Zeitrahmens abonnieren.
Höchste und niedrigste Schlusskurse über den Zeitraum mit den Indikatoren Highest und Lowest verfolgen.
Wenn der Preis über den höchsten Schlusskurs bricht, Aufwärtstrend signalisieren; wenn unter dem niedrigsten Schlusskurs, Abwärtstrend signalisieren.
Positionen entsprechend dem neuen Trend und den aktivierten Optionen eingehen oder verlassen.
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>
/// Trend arrows strategy based on breakouts of recent extremes.
/// Detects when price moves above the highest close or below the lowest close
/// over the specified period and trades in the direction of the breakout.
/// </summary>
public class TrendArrowsStrategy : Strategy
{
private readonly StrategyParam<int> _period;
private readonly StrategyParam<DataType> _candleType;
private bool _prevTrendUp;
private bool _prevTrendDown;
private decimal? _prevHighest;
private decimal? _prevLowest;
public int Period { get => _period.Value; set => _period.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public TrendArrowsStrategy()
{
_period = Param(nameof(Period), 15)
.SetDisplay("Period", "Number of bars for extreme calculation", "Parameters")
.SetOptimize(5, 30, 5);
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe of candles", "Parameters");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevTrendUp = false;
_prevTrendDown = false;
_prevHighest = null;
_prevLowest = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevTrendUp = false;
_prevTrendDown = false;
_prevHighest = null;
_prevLowest = null;
var highest = new Highest { Length = Period };
var lowest = new Lowest { Length = Period };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(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, decimal highestVal, decimal lowestVal)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
// Use previous bar's highest/lowest to detect breakout
if (_prevHighest is null || _prevLowest is null)
{
_prevHighest = highestVal;
_prevLowest = lowestVal;
return;
}
var trendUp = false;
var trendDown = false;
if (candle.ClosePrice > _prevHighest.Value)
trendUp = true;
else if (candle.ClosePrice < _prevLowest.Value)
trendDown = true;
else
{
trendUp = _prevTrendUp;
trendDown = _prevTrendDown;
}
// Buy when up trend appears
if (!_prevTrendUp && trendUp && Position <= 0)
BuyMarket();
// Sell when down trend appears
if (!_prevTrendDown && trendDown && Position >= 0)
SellMarket();
_prevTrendUp = trendUp;
_prevTrendDown = trendDown;
_prevHighest = highestVal;
_prevLowest = lowestVal;
}
}
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 Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class trend_arrows_strategy(Strategy):
def __init__(self):
super(trend_arrows_strategy, self).__init__()
self._period = self.Param("Period", 15) \
.SetDisplay("Period", "Number of bars for extreme calculation", "Parameters")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe of candles", "Parameters")
self._prev_trend_up = False
self._prev_trend_down = False
self._prev_highest = None
self._prev_lowest = None
@property
def period(self):
return self._period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(trend_arrows_strategy, self).OnReseted()
self._prev_trend_up = False
self._prev_trend_down = False
self._prev_highest = None
self._prev_lowest = None
def OnStarted2(self, time):
super(trend_arrows_strategy, self).OnStarted2(time)
self._prev_trend_up = False
self._prev_trend_down = False
self._prev_highest = None
self._prev_lowest = None
highest = Highest()
highest.Length = self.period
lowest = Lowest()
lowest.Length = self.period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(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_val, lowest_val):
if candle.State != CandleStates.Finished:
return
highest_val = float(highest_val)
lowest_val = float(lowest_val)
close_price = float(candle.ClosePrice)
if self._prev_highest is None or self._prev_lowest is None:
self._prev_highest = highest_val
self._prev_lowest = lowest_val
return
trend_up = False
trend_down = False
if close_price > self._prev_highest:
trend_up = True
elif close_price < self._prev_lowest:
trend_down = True
else:
trend_up = self._prev_trend_up
trend_down = self._prev_trend_down
if not self._prev_trend_up and trend_up and self.Position <= 0:
self.BuyMarket()
if not self._prev_trend_down and trend_down and self.Position >= 0:
self.SellMarket()
self._prev_trend_up = trend_up
self._prev_trend_down = trend_down
self._prev_highest = highest_val
self._prev_lowest = lowest_val
def CreateClone(self):
return trend_arrows_strategy()