Trendfolgende Stop-Loss-Strategie basierend auf TFO und ATR


Erstellungsdatum: 2023-12-04 13:32:41 zuletzt geändert: 2023-12-04 13:32:41
Kopie: 4 Klicks: 827
1
konzentrieren Sie sich auf
1619
Anhänger

Trendfolgende Stop-Loss-Strategie basierend auf TFO und ATR

Überblick

Die Strategie basiert auf Dr. John Ehlers Trend-Flex-Oszillator (Trend Flex Oscillator, TFO) und dem Indikator für die durchschnittliche wahre Bandbreite (Average True Range, ATR) und ist eine Trend-Tracking-Stopp-Strategie. Sie gilt für überschüssige Märkte, in denen bei einer Preisumkehr nach einem Oversold eine überschüssige Position eröffnet wird. Sie wird in der Regel innerhalb weniger Tage platziert, es sei denn, sie wird von einem Bärenmarkt gefangen, in dem Fall hält sie ihre Position.

Strategieprinzip

Die Strategie kombiniert die beiden Indikatoren TFO und ATR, indem sie übertrieben wird, wenn die Kaufbedingungen erfüllt sind, und platziert wird, wenn die Verkaufsbedingungen erfüllt sind.

Kaufbedingungen: Wenn der TFO unter einem bestimmten Schwellenwert liegt (zeigt übermäßige Leerstand), und der TFO-Wert der oberen K-Linie unter der aktuellen K-Linie ist (zeigt, dass der TFO rückläufig steigt), und der ATR über der festgelegten Schwankungsschwelle ist (zeigt, dass die Marktfluktuation zunimmt), werden diese drei Bedingungen erfüllt.

Die Strategie setzt außerdem ein Tracking-Stop-Loss ein, bei dem alle Positionen ausgeglichen werden, wenn der Preis den festgelegten Tracking-Stop-Loss-Preis überschreitet. Benutzer können wählen, ob die Strategie nach dem Kennzeichen-Signal platziert wird oder nur nach dem Preis-Loss-Plating.

Die Strategie kann bis zu 15 Positionen gleichzeitig eröffnen. Die Parameter können für verschiedene Zeitspannen angepasst werden.

Strategische Vorteile

  1. Die Kombination von Trend und Schwankungen zur Bestimmung der Marktrichtung ist relativ stabil. TFO kann frühe Signale für einen Trendbruch erfassen, ATR kann die Zeit erfassen, in der die Marktfluktuation zunimmt.

  2. Es gibt ein flexibles Set von Kauf- und Verkaufsparametern und Stop-Loss-Parametern. Der Benutzer kann die Parameter an den Markt anpassen, um die Optimierung zu erreichen.

  3. Die integrierte Stop-Loss-Funktion reduziert die Verluste bei Extremsituationen. Stop-Loss-Strategien sind ein wichtiger Bestandteil des Quantitative Trading.

  4. Unterstützt zusätzliche Auf- und Teil-Plating-Positionen, die durch die Erhöhung der Positionen den Gewinn erhöhen können.

Strategisches Risiko

  1. Diese Strategie ist nur zu viel zu tun, ohne zu verlieren, und kann nicht profitieren, wenn die Märkte fallen. Es kann zu großen Verlusten führen, wenn es zu einem schrecklichen Bärenmarkt kommt.

  2. Unkorrekt eingestellte Parameter können zu Übertriebenen oder Ausverkaufungen führen. Es muss wiederholt getestet werden, um die optimale Kombination von Parametern zu finden.

  3. In extremen Situationen kann ein Stop-Loss unwirksam sein und große Verluste nicht verhindern. Dies ist ein Problem, mit dem alle Stop-Loss-Strategien konfrontiert sein können.

  4. Die Rückschätzung kann nicht vollständig den tatsächlichen Handel widerspiegeln, und die tatsächlichen Ergebnisse werden von der tatsächlichen Abweichung abweichen.

Strategieoptimierung

  1. Es kann in Betracht gezogen werden, eine mobile Stop-Line in die Verkaufsbedingungen aufzunehmen, damit die Strategie den Verlust rechtzeitig stoppt und das Abwärtsrisiko effektiv kontrolliert.

  2. Es ist möglich, die Deckung zu erweitern, um die Position zu öffnen, wenn der TFO rückläufig ist und die ATR groß genug ist, um die Strategie für den Leerlaufmarkt anzuwenden.

  3. Weitere Filterbedingungen können hinzugefügt werden, z. B. die Veränderung der Transaktionsmenge, um die Auswirkung von Ausnahmezuständen auf die Strategie zu reduzieren.

  4. Die Parameter-Einstellungen und Rückmessungen für verschiedene Zeiträume können getestet werden, um die optimale Perioden- und Parameterkombination zu finden.

Zusammenfassen

Die Strategie integriert die Vorteile der Trendanalyse und der Volatilitätsüberwachung, um die Richtung des Marktes anhand einer Kombination von TFO- und ATR-Indikatoren zu bestimmen. Es gibt zusätzliche Mechanismen zum Eröffnen von Positionen, zum Teil zum Schließen von Positionen und zum Bewegen von Stop-Losses, um die Gewinne zu erhöhen und das Risiko zu kontrollieren.

Strategiequellcode
/*backtest
start: 2022-11-27 00:00:00
end: 2023-12-03 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Chart0bserver 
//
// Open Source attributions:
// portions © allanster (date window code)
// portions © Dr. John Ehlers (Trend Flex Oscillator)
//
// READ THIS CAREFULLY!!! ----------------//
// This code is provided for educational purposes only.  The results of this strategy should not be considered investment advice.
// The user of this script acknolwedges that it can cause serious financial loss when used as a trading tool
// This strategy has a bias for HODL (Holds on to Losses) meaning that it provides NO STOP LOSS protection! 
// Also note that the default behavior is designed for up to 15 open long orders, and executes one order to close them all at once. 
// Opening a long position is predicated on The Trend Flex Oscillator (TFO) rising after being oversold, and ATR above a certain volatility threshold.
// Closing a long is handled either by TFO showing overbought while above a certain ATR level, or the Trailing Stop Loss.  Pick one or both.
// If the strategy is allowed to sell before a Trailing Stop Loss is triggered, you can set a "must exceed %".  Do not mistake this for a stop loss.
// Short positions are not supported in this version.  Back-testing should NEVER be considered an accurate representation of actual trading results.

//@version=5
strategy('TFO + ATR Strategy with Trailing Stop Loss', 'TFO ATR Trailing Stop Loss', overlay=true, pyramiding=15, default_qty_type=strategy.cash, default_qty_value=10000, initial_capital=150000, currency='USD', commission_type=strategy.commission.percent, commission_value=0.5)
strategy.risk.allow_entry_in(strategy.direction.long)  // There will be no short entries, only exits from long.

// -----------------------------------------------------------------------------------------------------------//
// Back-testing Date Range code  ----------------------------------------------------------------------------//
// ---------------------------------------------------------------------------------------------------------//
fromMonth = input.int(defval=9, title='From Month', minval=1, maxval=12, group='Back-Testing Start Date')
fromDay = input.int(defval=1, title='From Day', minval=1, maxval=31, group='Back-Testing Start Date')
fromYear = input.int(defval=2021, title='From Year', minval=1970, group='Back-Testing Start Date')
thruMonth = 1       //input(defval = 1,    title = "Thru Month",      type = input.integer, minval = 1, maxval = 12, group="Back-Testing Date Range")
thruDay = 1         //input(defval = 1,    title = "Thru Day",        type = input.integer, minval = 1, maxval = 31, group="Back-Testing Date Range")
thruYear = 2112     //input(defval = 2112, title = "Thru Year",       type = input.integer, minval = 1970, group="Back-Testing Date Range")

// === FUNCTION EXAMPLE ===
start = timestamp(fromYear, fromMonth, fromDay, 00, 00)  // backtest start window
finish = timestamp(thruYear, thruMonth, thruDay, 23, 59)  // backtest finish window
window() =>  // create function "within window of time
    time >= start and time <= finish ? true : false
// Date range code -----//



// -----------------------------------------------------------------------------------------------------------//
// ATR Indicator Code  --------------------------------------------------------------------------------------//
// ---------------------------------------------------------------------------------------------------------//
length = 18  //input(title="ATR Length", defval=18, minval=1)
Period = 18  //input(18,title="ATR EMA Period")  

basicEMA = ta.ema(close, length)
ATR_Function = ta.ema(ta.tr(true), length)
EMA_ATR = ta.ema(ATR_Function, Period)
ATR = ta.ema(ta.tr(true), length)
ATR_diff = ATR - EMA_ATR
volatility = 100 * ATR_diff / EMA_ATR  // measure of spread between ATR and EMA
volatilityAVG = math.round((volatility + volatility[1] + volatility[2]) / 3)
buyVolatility = input.int(3, 'Min Volatility for Buy', minval=-20, maxval=20, step=1, group='Average True Range')
sellVolatility = input.int(13, 'Min Volatility for Sell', minval=-10, maxval=20, step=1, group='Average True Range')
useAvgVolatility = input.bool(defval=false, title='Average the Volatility over 3 bars', group='Average True Range')
// End of ATR  ------------/


// -----------------------------------------------------------------------------------------------------------//
// TFO Indicator code  --------------------------------------------------------------------------------------//
// ---------------------------------------------------------------------------------------------------------//
trendflex(Series, PeriodSS, PeriodTrendFlex, PeriodEMA) =>
    var SQRT2xPI = math.sqrt(8.0) * math.asin(1.0)  // 4.44288293815 Constant
    alpha = SQRT2xPI / PeriodSS
    beta = math.exp(-alpha)
    gamma = -beta * beta
    delta = 2.0 * beta * math.cos(alpha)
    float superSmooth = na
    superSmooth := (1.0 - delta - gamma) * (Series + nz(Series[1])) * 0.5 + delta * nz(superSmooth[1]) + gamma * nz(superSmooth[2])
    E = 0.0
    for i = 1 to PeriodTrendFlex by 1
        E += superSmooth - nz(superSmooth[i])
        E
    epsilon = E / PeriodTrendFlex
    zeta = 2.0 / (PeriodEMA + 1.0)
    float EMA = na
    EMA := zeta * epsilon * epsilon + (1.0 - zeta) * nz(EMA[1])
    return_1 = EMA == 0.0 ? 0.0 : epsilon / math.sqrt(EMA)
    return_1

upperLevel = input.float(1.2, 'TFO Upper Level', minval=0.1, maxval=2.0, step=0.1, group='Trend Flex Ocillator')
lowerLevel = input.float(-0.9, 'TFO Lower Level', minval=-2.0, maxval=-0.1, step=0.1, group='Trend Flex Ocillator')
periodTrendFlex = input.int(14, 'TrendFlex Period', minval=2, group='Trend Flex Ocillator')
useSuperSmootherOveride = true  //input( true, "Apply SuperSmoother Override Below*", input.bool, group="Trend Flex Ocillator")
periodSuperSmoother = 8.0       //input(8.0, "SuperSmoother Period*", input.float  , minval=4.0, step=0.5, group="Trend Flex Ocillator")
postSmooth = 33                 //input(33.0, "Post Smooth Period**", input.float  , minval=1.0, step=0.5, group="Trend Flex Ocillator")

trendFlexOscillator = trendflex(close, periodSuperSmoother, periodTrendFlex, postSmooth)
// End of TFO -------------//


// -----------------------------------------------------------------------------------------------------------//
// HODL Don't sell if losing n% ---------------------------------------------------------------------------- //
// ---------------------------------------------------------------------------------------------------------// 
sellOnStrategy = input.bool(defval=true, title='Allow Stategy to close positions', group='Selling Conditions')
doHoldLoss = true       // input(defval = true, title = "Strategy can sell for a loss", type = input.bool, group="Selling Conditions")
holdLoss = input.int(defval=0, title='Value (%) must exceed ', minval=-25, maxval=10, step=1, group='Selling Conditions')
totalInvest = strategy.position_avg_price * strategy.position_size
openProfitPerc = strategy.openprofit / totalInvest
bool acceptableROI = openProfitPerc * 100 > holdLoss
// -----------------------//



// -----------------------------------------------------------------------------------------------------------//
// Buying and Selling conditions  -------------------------------------------------------------------------- //
// ---------------------------------------------------------------------------------------------------------//    
if useAvgVolatility
    volatility := volatilityAVG
    volatility
tfoBuy = trendFlexOscillator < lowerLevel and trendFlexOscillator[1] < trendFlexOscillator  // Always make a purchase if TFO is in this lowest range
atrBuy = volatility > buyVolatility
tfoSell = ta.crossunder(trendFlexOscillator, upperLevel)
consensusBuy = tfoBuy and atrBuy
consensusSell = tfoSell and volatility > sellVolatility
if doHoldLoss
    consensusSell := consensusSell and acceptableROI
    consensusSell
// --------------------//



// -----------------------------------------------------------------------------------------------------------//
// Tracing & Debugging --------------------------------------------------------------------------------------//
// ---------------------------------------------------------------------------------------------------------//

plotchar(strategy.opentrades, 'Number of open trades', ' ', location.top)
plotarrow(100 * openProfitPerc, 'Profit on open longs', color.new(color.green, 75), color.new(color.red, 75))
// plotchar(strategy.position_size, "Shares on hand", " ", location.top)
// plotchar(totalInvest, "Total Invested", " ", location.top)
// plotarrow(strategy.openprofit, "Open profit dollar amount", color.new(color.green,100), color.new(color.red, 100))
// plotarrow(strategy.netprofit, "Net profit for session", color.new(color.green,100), color.new(color.red, 100))
// plotchar(acceptableROI, "Acceptable ROI", " ", location.top)
// plotarrow(volatility, "ATR volatility value", color.new(color.green,75), color.new(color.red, 75))
// plotchar(strategy.position_avg_price, "Avgerage price of holdings", " ", location.top)
// plotchar(volatilityAVG, "AVG volatility", " ", location.top)
// plotchar(fiveBarsVal, "change in 5bars", " ", location.top)
// plotchar(crossingUp, "crossingUp", "x",  location.belowbar, textcolor=color.white)
// plotchar(crossingDown, "crossingDn", "x",  location.abovebar, textcolor=color.white)
// plotchar(strategy.closedtrades, "closedtrades", " ", location.top)
// plotchar(strategy.wintrades, "wintrades", " ", location.top)
// plotchar(strategy.losstrades, "losstrades", " ", location.top)
// plotchar(close, "close", " ", location.top)
//--------------------//

// -----------------------------------------------------------------------------------------------------------//
// Trade Alert Execution ------------------------------------------------------------------------------------//
// ---------------------------------------------------------------------------------------------------------//

strategy.entry('long', strategy.long, when=window() and consensusBuy, comment='long')
if sellOnStrategy
    strategy.close('long', when=window() and consensusSell, qty_percent=100, comment='Strat')


// -----------------------------------------------------------------------------------------------------------//
// Trailing Stop Loss logic -------------------------------------------------------------------------------- //
// ---------------------------------------------------------------------------------------------------------//    
useTrailStop = input.bool(defval=true, title='Set Trailing Stop Loss on avg positon value', group='Selling Conditions')
arm = input.float(defval=15, title='Trailing Stop Arms At (%)', minval=1, maxval=30, step=1, group='Selling Conditions') * 0.01
trail = input.float(defval=2, title='Trailing Stop Loss (%)', minval=0.25, maxval=9, step=0.25, group='Selling Conditions') * 0.1

longStopPrice = 0.0
stopLossPrice = 0.0

if strategy.position_size > 0
    longStopPrice := strategy.position_avg_price * (1 + arm)
    stopLossPrice := strategy.position_avg_price * ((100 - math.abs(holdLoss)) / 100)  // for use with 'stop' in strategy.exit
    stopLossPrice
else
    longStopPrice := close
    longStopPrice

// If you want to hide the Trailing Stop Loss threshold (green line), comment this out
plot(longStopPrice, 'Arm Trail Stop at', color.new(color.green, 60), linewidth=2)

if strategy.position_size > 0 and useTrailStop
    strategy.exit('exit', 'long', when=window(), qty_percent=100, trail_price=longStopPrice, trail_offset=trail * close / syminfo.mintick, comment='Trail')

//-----------------------------------------------------------------------------------------------------------//