Spirale Breakout-Strategie für den gleitenden Durchschnitt

Schriftsteller:ChaoZhang, Datum: 2024-01-15 11:45:23
Tags:

img

Übersicht

Diese Strategie kombiniert den Spiral Channel-Indikator und den Rate of Change (ROC) -Indikator. Sie erzeugt Kaufsignale, wenn der Preis durch das obere Band und den gleitenden Durchschnitt bricht, und Verkaufssignale, wenn der Preis durch das untere Band und den gleitenden Durchschnitt bricht. Der Spiral Channel bestimmt die Trendrichtung, während der ROC die Preisdynamik erkennt. Durch die Anforderung einer Vereinbarung zwischen beiden Indikatoren zielt die Strategie darauf ab, die Zuverlässigkeit der Handelssignale und die Gewinnrate zu verbessern.

Strategie Logik

Die Strategie beruht auf zwei Schlüsselindikatoren:

  1. Spiralkanäle: Zeichnen Sie die oberen und unteren Bands auf, um die Trendrichtung zu bestimmen.

  2. Rate of Change (ROC): Erkennt eine Preisbeschleunigung. ROC über einer positiven Schwelle deutet auf eine beschleunigte Aufwärtsbewegung der Preise hin, während ROC unter einer negativen Schwelle auf eine beschleunigte Abwärtsbewegung hindeutet.

Kaufsignale werden erzeugt, wenn sowohl der Spiral Channel als auch die ROC bullische Anzeichen geben, nämlich ein Preisbruch über den oberen Bereich in Verbindung mit einer beschleunigten Aufwärtsdynamik. Verkaufssignale werden ausgelöst, wenn beide Indikatoren bärisch werden.

Die kombinierten Signale helfen, gegen den Trend gehandelt zu vermeiden und die Zuverlässigkeit zu verbessern.

Vorteile

  1. Zuverlässige Signale mit einer höheren Gewinnrate, da eine Übereinstimmung zwischen Trend und Dynamik erforderlich ist.

  2. Anpassungsfähige Handelsfrequenz durch Parameter-Tuning, z. B. Anpassung der ROC-Parameter.

  3. Stop-Loss, um das Abwärtsrisiko einzelner Trades zu begrenzen.

  4. Einführung eines neuen Mechanismus zur Steigerung der Rentabilität.

Risiken

  1. Einige Handelschancen fehlen und das Gewinnpotenzial aufgrund der Anforderungen an die Signalzuverlässigkeit begrenzt wird.

  2. Anfällig dafür, wenn der Trend umkehrt und möglicherweise zu großen Verlusten führt.

  3. Eine schlechte Abstimmung der Parameter kann zu zu wenig oder zu vielen Signalen führen.

  4. Festgelegte Stop-Loss-Prozentsätze, die keine schweren Verluste bei enormen Preisschwankungen verhindern können.

Möglichkeiten zur Verbesserung

  1. Optimieren Sie die ROC-Parameter für eine optimale Leistung.

  2. Testen Sie verschiedene Stop-Loss-Level, um Risiko und Gewinn auszugleichen.

  3. Fügen Sie andere Filter wie Volumen, Volatilitätsindikatoren hinzu, um Signale zu verfeinern.

  4. Bewertet die Leistung auf verschiedenen Märkten, um die beste Passform zu finden.

  5. Einführung dynamischer Positionsgrößen für unterschiedliche Marktbedingungen.

Schlussfolgerung

Die Strategie kombiniert Spiral Channel und ROC, um die Trendrichtung und -dynamik zu bewerten. Sie zielt auf Signalzuverlässigkeit ab und behält gleichzeitig die Rentabilität durch Wiedereintritt und Parameter-Tuning bei. Das Risiko wird hauptsächlich durch einen festen Prozentsatz Stop-Loss kontrolliert. Insgesamt ist es ein relativ vollständiger Rahmen, der als grundlegende quantitative Handelsstrategie geeignet ist.


/*backtest
start: 2024-01-07 00:00:00
end: 2024-01-14 00:00:00
period: 45m
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("SSL Chaikin BF 🚀", overlay=true, precision=2, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.075)

/////////////// Time Frame ///////////////
_0 = input(false,  "════════ Test Period ═══════")
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

testPeriod() => true

/////////////// Chaikin MF /////////////// 
_1 = input(false,  "═══════ Chaikin MF ═══════")
length = input(20, minval=1, title = "Chaikin SMA Length")
upperThreshold = input(0.04, step=0.01, title="Upper Threshold")
lowerThreshold = input(0.02, step=0.01, title="Lower Threshold")
ad = close==high and close==low or high==low ? 0 : ((2*close-low-high)/(high-low))*volume
mf = sum(ad, length) / sum(volume, length)

/////////////// SSL Channels /////////////// 
_2 = input(false,  "═════════ SSL ══════════")
len1=input(title="SMA Length 1", defval=12)
len2=input(title="SMA Length 2", defval=13)

smaHigh = sma(high, len1)
smaLow = sma(low, len2)

Hlv = 0
Hlv := close > smaHigh ? 1 : close < smaLow ? -1 : Hlv[1]
sslDown = Hlv < 0 ? smaHigh : smaLow
sslUp = Hlv < 0 ? smaLow : smaHigh

///////////// Rate Of Change ///////////// 
_3 = input(false,  "══════ Rate of Change ══════")
source = close
roclength = input(13, "ROC Length",  minval=1)
pcntChange = input(4, "ROC % Change", minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))

///////////////  Strategy  /////////////// 
long = sslUp > sslDown and isMoving() or crossover(mf, upperThreshold)
short = sslUp < sslDown and isMoving() or crossunder(mf, lowerThreshold)

last_long = 0.0
last_short = 0.0
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = 0.0
last_open_short_signal = 0.0
last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = 0.0
last_short_signal = 0.0
last_long_signal := long_signal ? time : nz(last_long_signal[1])
last_short_signal := short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = 0.0
last_low = 0.0
last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) 

//////////////// Stop loss /////////////// 
_4 = input(false,  "════════ Stop Loss ═══════")
sl_inp = input(2.0, title='Stop Loss %') / 100

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

/////////////// Execution /////////////// 
if testPeriod()
    strategy.entry("L", strategy.long, when=long)
    strategy.entry("S", strategy.short, when=short)
    strategy.exit("L SL", "L", stop=long_sl, when=since_longEntry > 0)
    strategy.exit("S SL", "S", stop=short_sl, when=since_shortEntry > 0)

/////////////// Plotting /////////////// 
p1 = plot(sslDown, linewidth = 1, color=color.red)
p2 = plot(sslUp, linewidth = 1, color=color.lime)
fill(p1, p2,  color = sslDown < sslUp ? color.lime : color.red, transp=80)
bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80)
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30)
bgcolor(crossover(mf, upperThreshold) ? color.blue : crossunder(mf, lowerThreshold) ? color.orange : na, transp=30)

Mehr