SilverTrend Signal ReOpen-Strategie
Strategie basierend auf dem SilverTrend-Indikator mit optionalem Wiedereinstieg. Öffnet eine Position, wenn der Indikator die Richtung ändert, und fügt bei jedem definierten Preisschritt zugunsten des Trades zusätzliche Positionen hinzu. Positionen können bei entgegengesetzten Signalen oder beim Erreichen von Stop-Loss / Take-Profit-Niveaus geschlossen werden.
Details
- Einstiegskriterien:
- Long: SilverTrend-Indikator wechselt von Abwärtstrend zu Aufwärtstrend
- Short: SilverTrend-Indikator wechselt von Aufwärtstrend zu Abwärtstrend
- Long/Short: Beide
- Ausstiegskriterien:
- Optional bei entgegengesetzten SilverTrend-Signalen schließen
- Stop-Loss oder Take-Profit erreicht
- Stops: Absolute Preisniveaus
- Standardwerte:
CandleType= TimeSpan.FromHours(4).TimeFrame()Ssp= 9Risk= 3PriceStep= 300mPosTotal= 10StopLoss= 1000mTakeProfit= 2000mBuyPosOpen= trueSellPosOpen= trueBuyPosClose= trueSellPosClose= true
- Filter:
- Kategorie: Trend
- Richtung: Beide
- Indikatoren: SilverTrend
- Stops: Ja
- Komplexität: Mittel
- Zeitrahmen: Mittelfristig
- Saisonalität: Nein
- Neuronale Netze: Nein
- Divergenz: Nein
- Risikolevel: Mittel
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy using SilverTrend-style indicator logic with optional position re-opening.
/// Uses Williams %R zone detection to identify trend changes.
/// Re-opens positions in the trend direction at fixed price intervals.
/// </summary>
public class SilverTrendSignalReOpenStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _ssp;
private readonly StrategyParam<int> _risk;
private readonly StrategyParam<decimal> _priceStep;
private readonly StrategyParam<int> _posTotal;
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<decimal> _takeProfit;
private decimal _entryPrice;
private decimal _lastReopenPrice;
private int _positionsCount;
private bool _uptrend;
private bool _prevUptrend;
private bool _hasPrev;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int Ssp { get => _ssp.Value; set => _ssp.Value = value; }
public int Risk { get => _risk.Value; set => _risk.Value = value; }
public decimal PriceStep { get => _priceStep.Value; set => _priceStep.Value = value; }
public int PosTotal { get => _posTotal.Value; set => _posTotal.Value = value; }
public decimal StopLoss { get => _stopLoss.Value; set => _stopLoss.Value = value; }
public decimal TakeProfit { get => _takeProfit.Value; set => _takeProfit.Value = value; }
public SilverTrendSignalReOpenStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
_ssp = Param(nameof(Ssp), 9)
.SetGreaterThanZero()
.SetDisplay("SSP", "Williams %R period", "Indicators");
_risk = Param(nameof(Risk), 3)
.SetGreaterThanZero()
.SetDisplay("Risk", "Risk parameter for zone width", "Indicators");
_priceStep = Param(nameof(PriceStep), 1000m)
.SetGreaterThanZero()
.SetDisplay("Price Step", "Distance to add position", "Trading");
_posTotal = Param(nameof(PosTotal), 1)
.SetGreaterThanZero()
.SetDisplay("Max Positions", "Maximum number of positions", "Trading");
_stopLoss = Param(nameof(StopLoss), 1000m)
.SetGreaterThanZero()
.SetDisplay("Stop Loss", "Stop loss distance", "Trading");
_takeProfit = Param(nameof(TakeProfit), 2000m)
.SetGreaterThanZero()
.SetDisplay("Take Profit", "Take profit distance", "Trading");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_entryPrice = 0m;
_lastReopenPrice = 0m;
_positionsCount = 0;
_uptrend = false;
_prevUptrend = false;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
_uptrend = false;
_prevUptrend = false;
_positionsCount = 0;
_entryPrice = 0m;
_lastReopenPrice = 0m;
var rsi = new RelativeStrengthIndex { Length = Ssp };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, rsi);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal rsi)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
if (rsi < 40m)
_uptrend = false;
if (rsi > 60m)
_uptrend = true;
var buySignal = !_prevUptrend && _uptrend;
var sellSignal = _prevUptrend && !_uptrend;
if (_hasPrev)
{
// Check exits for existing positions
if (Position > 0)
{
var stopPrice = _entryPrice - StopLoss;
var takePrice = _entryPrice + TakeProfit;
if (sellSignal || close <= stopPrice || close >= takePrice)
{
SellMarket(Math.Abs(Position));
_positionsCount = 0;
_entryPrice = 0m;
_lastReopenPrice = 0m;
}
else if (PriceStep > 0m && close - _lastReopenPrice >= PriceStep && _positionsCount < PosTotal)
{
BuyMarket();
_lastReopenPrice = close;
_positionsCount++;
}
}
else if (Position < 0)
{
var stopPrice = _entryPrice + StopLoss;
var takePrice = _entryPrice - TakeProfit;
if (buySignal || close >= stopPrice || close <= takePrice)
{
BuyMarket(Math.Abs(Position));
_positionsCount = 0;
_entryPrice = 0m;
_lastReopenPrice = 0m;
}
else if (PriceStep > 0m && _lastReopenPrice - close >= PriceStep && _positionsCount < PosTotal)
{
SellMarket();
_lastReopenPrice = close;
_positionsCount++;
}
}
// Open new positions on signal
if (Position == 0)
{
if (buySignal)
{
BuyMarket();
_entryPrice = close;
_lastReopenPrice = close;
_positionsCount = 1;
}
else if (sellSignal)
{
SellMarket();
_entryPrice = close;
_lastReopenPrice = close;
_positionsCount = 1;
}
}
}
_prevUptrend = _uptrend;
_hasPrev = true;
}
}
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, Unit, UnitTypes
from StockSharp.Algo.Indicators import RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class silver_trend_signal_re_open_strategy(Strategy):
def __init__(self):
super(silver_trend_signal_re_open_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1)))
self._ssp = self.Param("Ssp", 9)
self._risk = self.Param("Risk", 3)
self._price_step_param = self.Param("PriceStep", 1000.0)
self._pos_total = self.Param("PosTotal", 1)
self._stop_loss = self.Param("StopLoss", 1000.0)
self._take_profit = self.Param("TakeProfit", 2000.0)
self._entry_price = 0.0
self._last_reopen_price = 0.0
self._positions_count = 0
self._uptrend = False
self._prev_uptrend = False
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def Ssp(self):
return self._ssp.Value
@Ssp.setter
def Ssp(self, value):
self._ssp.Value = value
@property
def Risk(self):
return self._risk.Value
@Risk.setter
def Risk(self, value):
self._risk.Value = value
@property
def PriceStepParam(self):
return self._price_step_param.Value
@PriceStepParam.setter
def PriceStepParam(self, value):
self._price_step_param.Value = value
@property
def PosTotal(self):
return self._pos_total.Value
@PosTotal.setter
def PosTotal(self, value):
self._pos_total.Value = value
@property
def StopLoss(self):
return self._stop_loss.Value
@StopLoss.setter
def StopLoss(self, value):
self._stop_loss.Value = value
@property
def TakeProfit(self):
return self._take_profit.Value
@TakeProfit.setter
def TakeProfit(self, value):
self._take_profit.Value = value
def OnStarted2(self, time):
super(silver_trend_signal_re_open_strategy, self).OnStarted2(time)
self._has_prev = False
self._uptrend = False
self._prev_uptrend = False
self._positions_count = 0
self._entry_price = 0.0
self._last_reopen_price = 0.0
rsi = RelativeStrengthIndex()
rsi.Length = self.Ssp
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, self.ProcessCandle).Start()
self.StartProtection(
Unit(2000.0, UnitTypes.Absolute),
Unit(1000.0, UnitTypes.Absolute))
def ProcessCandle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
rsi_val = float(rsi_value)
if rsi_val < 40.0:
self._uptrend = False
if rsi_val > 60.0:
self._uptrend = True
buy_signal = not self._prev_uptrend and self._uptrend
sell_signal = self._prev_uptrend and not self._uptrend
sl = float(self.StopLoss)
tp = float(self.TakeProfit)
ps = float(self.PriceStepParam)
max_pos = int(self.PosTotal)
if self._has_prev:
if self.Position > 0:
stop_price = self._entry_price - sl
take_price = self._entry_price + tp
if sell_signal or close <= stop_price or close >= take_price:
self.SellMarket()
self._positions_count = 0
self._entry_price = 0.0
self._last_reopen_price = 0.0
elif ps > 0.0 and close - self._last_reopen_price >= ps and self._positions_count < max_pos:
self.BuyMarket()
self._last_reopen_price = close
self._positions_count += 1
elif self.Position < 0:
stop_price = self._entry_price + sl
take_price = self._entry_price - tp
if buy_signal or close >= stop_price or close <= take_price:
self.BuyMarket()
self._positions_count = 0
self._entry_price = 0.0
self._last_reopen_price = 0.0
elif ps > 0.0 and self._last_reopen_price - close >= ps and self._positions_count < max_pos:
self.SellMarket()
self._last_reopen_price = close
self._positions_count += 1
if self.Position == 0:
if buy_signal:
self.BuyMarket()
self._entry_price = close
self._last_reopen_price = close
self._positions_count = 1
elif sell_signal:
self.SellMarket()
self._entry_price = close
self._last_reopen_price = close
self._positions_count = 1
self._prev_uptrend = self._uptrend
self._has_prev = True
def OnReseted(self):
super(silver_trend_signal_re_open_strategy, self).OnReseted()
self._entry_price = 0.0
self._last_reopen_price = 0.0
self._positions_count = 0
self._uptrend = False
self._prev_uptrend = False
self._has_prev = False
def CreateClone(self):
return silver_trend_signal_re_open_strategy()