S7 Up Bot-Strategie
Ausbruchsystem, das nach nahezu gleichen Hochs oder Tiefs sucht, gefolgt von einer scharfen Preisbewegung.
Wenn zwei aufeinanderfolgende Tiefs fast gleich sind und der Preis um Span Price steigt, geht der Bot long.
Es geht short, wenn sich zwei Hochs angleichen und der Preis um Span Price fällt.
Positionen werden mit optionalen Take-Profit-, Stop-Loss-, Trailing-Stop- und Frühaustiegsfunktionen geschützt.
Details
- Einstiegskriterien:
- Kauf: Differenz zwischen aktuellem und vorherigem Tief liegt unter
HL Divergence und der Preis liegt Span Price über dem Tief.
- Verkauf: Differenz zwischen aktuellem und vorherigem Hoch liegt unter
HL Divergence und der Preis liegt Span Price unter dem Hoch.
- Long/Short: Beide.
- Ausstiegskriterien:
- Take-Profit oder Stop-Loss.
- Trailing-Stop oder Null-Trailing-Anpassung.
- Frühaustieg, wenn der Preis das vorherige Hoch/Tief kreuzt (
Exit At Extremum) oder sich dem Umkehrniveau nähert (Exit At Reversal).
- Stops: Absolute Take-Profit und Stop-Loss mit optionalem Trailing.
- Filter: Keine.
Parameter
Take Profit – Gewinnziel in Preiseinheiten.
Stop Loss – Verlustlimit in Preiseinheiten, 0 für automatischen extremwertbasierten Stop.
HL Divergence – maximal zulässige Differenz zwischen zwei aufeinanderfolgenden Hochs oder Tiefs.
Span Price – Abstand vom Extremwert zum Preis für den Einstieg.
Max Trades – maximale gleichzeitige Trades.
Use Trailing Stop – Trailing-Stop-Mechanismus aktivieren.
Trail Stop – Trailing-Stop-Abstand.
Zero Trailing – Stop in Richtung Preis bewegen, sobald Position profitabel ist.
Step Trailing – minimaler Schritt zur Anpassung des Null-Trailings.
Exit At Extremum – schließen, wenn Preis das vorherige Hoch/Tief kreuzt.
Exit At Reversal – schließen, wenn Preis sich dem gegenüberliegenden Extremwert nähert.
Span To Revers – Abstand vom Extremwert zum Auslösen des Umkehrausstiegs.
Candle Type – Zeitrahmen für die Analyse.
Order Volume – Menge pro Trade.
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>
/// S7 Up Bot breakout strategy.
/// Opens long after double bottom and short after double top.
/// </summary>
public class S7UpBotStrategy : Strategy
{
private readonly StrategyParam<decimal> _takeProfit;
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<decimal> _hlDivergence;
private readonly StrategyParam<decimal> _spanPrice;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevLow;
private decimal _prevHigh;
private decimal _entryPrice;
private decimal _stopPrice;
private decimal _takeProfitPrice;
private bool _isLong;
private bool _inPosition;
public decimal TakeProfit { get => _takeProfit.Value; set => _takeProfit.Value = value; }
public decimal StopLoss { get => _stopLoss.Value; set => _stopLoss.Value = value; }
public decimal HlDivergence { get => _hlDivergence.Value; set => _hlDivergence.Value = value; }
public decimal SpanPrice { get => _spanPrice.Value; set => _spanPrice.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public S7UpBotStrategy()
{
_takeProfit = Param(nameof(TakeProfit), 500m)
.SetDisplay("Take Profit", "Absolute take profit", "Risk");
_stopLoss = Param(nameof(StopLoss), 300m)
.SetDisplay("Stop Loss", "Absolute stop loss", "Risk");
_hlDivergence = Param(nameof(HlDivergence), 100m)
.SetGreaterThanZero()
.SetDisplay("HL Divergence", "Max difference between highs or lows", "General");
_spanPrice = Param(nameof(SpanPrice), 50m)
.SetGreaterThanZero()
.SetDisplay("Span Price", "Distance from extreme to price", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Time frame for analysis", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevLow = 0m;
_prevHigh = 0m;
_entryPrice = 0m;
_stopPrice = 0m;
_takeProfitPrice = 0m;
_isLong = false;
_inPosition = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevLow = 0m;
_prevHigh = 0m;
_inPosition = false;
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 price = candle.ClosePrice;
if (_inPosition)
ManagePosition(candle, price);
if (!_inPosition && _prevLow != 0m && _prevHigh != 0m)
CheckEntry(candle, price);
_prevLow = candle.LowPrice;
_prevHigh = candle.HighPrice;
}
private void CheckEntry(ICandleMessage candle, decimal price)
{
// Double bottom: consecutive similar lows + bounce
if (Math.Abs(candle.LowPrice - _prevLow) < HlDivergence &&
price - candle.LowPrice > SpanPrice)
{
if (Position <= 0)
BuyMarket();
_inPosition = true;
_isLong = true;
_entryPrice = price;
_stopPrice = price - StopLoss;
_takeProfitPrice = price + TakeProfit;
}
// Double top: consecutive similar highs + drop
else if (Math.Abs(candle.HighPrice - _prevHigh) < HlDivergence &&
candle.HighPrice - price > SpanPrice)
{
if (Position >= 0)
SellMarket();
_inPosition = true;
_isLong = false;
_entryPrice = price;
_stopPrice = price + StopLoss;
_takeProfitPrice = price - TakeProfit;
}
}
private void ManagePosition(ICandleMessage candle, decimal price)
{
if (_isLong)
{
if (candle.HighPrice >= _takeProfitPrice || candle.LowPrice <= _stopPrice)
{
SellMarket();
_inPosition = false;
}
}
else
{
if (candle.LowPrice <= _takeProfitPrice || candle.HighPrice >= _stopPrice)
{
BuyMarket();
_inPosition = false;
}
}
}
}
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.Strategies import Strategy
class s7_up_bot_strategy(Strategy):
def __init__(self):
super(s7_up_bot_strategy, self).__init__()
self._take_profit = self.Param("TakeProfit", 500.0) \
.SetDisplay("Take Profit", "Absolute take profit", "Risk")
self._stop_loss = self.Param("StopLoss", 300.0) \
.SetDisplay("Stop Loss", "Absolute stop loss", "Risk")
self._hl_divergence = self.Param("HlDivergence", 100.0) \
.SetDisplay("HL Divergence", "Max difference between highs or lows", "General")
self._span_price = self.Param("SpanPrice", 50.0) \
.SetDisplay("Span Price", "Distance from extreme to price", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Time frame for analysis", "General")
self._prev_low = 0.0
self._prev_high = 0.0
self._entry_price = 0.0
self._stop_price = 0.0
self._take_profit_price = 0.0
self._is_long = False
self._in_position = False
@property
def take_profit(self):
return self._take_profit.Value
@property
def stop_loss(self):
return self._stop_loss.Value
@property
def hl_divergence(self):
return self._hl_divergence.Value
@property
def span_price(self):
return self._span_price.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(s7_up_bot_strategy, self).OnReseted()
self._prev_low = 0.0
self._prev_high = 0.0
self._entry_price = 0.0
self._stop_price = 0.0
self._take_profit_price = 0.0
self._is_long = False
self._in_position = False
def OnStarted2(self, time):
super(s7_up_bot_strategy, self).OnStarted2(time)
self._prev_low = 0.0
self._prev_high = 0.0
self._in_position = False
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
price = float(candle.ClosePrice)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
if self._in_position:
self._manage_position(candle, price)
if not self._in_position and self._prev_low != 0.0 and self._prev_high != 0.0:
self._check_entry(candle, price, high, low)
self._prev_low = low
self._prev_high = high
def _check_entry(self, candle, price, high, low):
hl_div = float(self.hl_divergence)
span = float(self.span_price)
tp = float(self.take_profit)
sl = float(self.stop_loss)
# Double bottom
if abs(low - self._prev_low) < hl_div and price - low > span:
if self.Position <= 0:
self.BuyMarket()
self._in_position = True
self._is_long = True
self._entry_price = price
self._stop_price = price - sl
self._take_profit_price = price + tp
# Double top
elif abs(high - self._prev_high) < hl_div and high - price > span:
if self.Position >= 0:
self.SellMarket()
self._in_position = True
self._is_long = False
self._entry_price = price
self._stop_price = price + sl
self._take_profit_price = price - tp
def _manage_position(self, candle, price):
high = float(candle.HighPrice)
low = float(candle.LowPrice)
if self._is_long:
if high >= self._take_profit_price or low <= self._stop_price:
self.SellMarket()
self._in_position = False
else:
if low <= self._take_profit_price or high >= self._stop_price:
self.BuyMarket()
self._in_position = False
def CreateClone(self):
return s7_up_bot_strategy()