Korrelationsbasierte bullische/bärenische Krypto-Handelsstrategie auf Basis des Wall Street CCI-Index

Schriftsteller:ChaoZhang, Datum: 2023-11-01 11:27:20
Tags:

img

Übersicht

Dies ist eine automatisierte Handelsstrategie, die mit Hilfe des Wall Street Chasing Ring Index lange/kurze/nahe Signale für die Ziel-Kryptowährung erzeugt, basierend auf dem berechneten Trend einer mit ihr korrelierten Benchmark-Kryptowährung.

Mit Standardparametern und ETH/USDT als Basis-Symbol zeigt die Strategie gute Backtest-Ergebnisse bei Symbolen wie DENT/USDT, BTT/USDT, FTT/USDT, DOT/USDT usw. Dies ist sinnvoll, da ETH in den Krypto-Märkten ziemlich einflussreich ist, so dass viele Kryptos dazu neigen, den großen Bewegungen von ETH zu folgen.

Hinweis: Die Strategie mit Standardparametern ist für einen Zeitrahmen von 4 Stunden vorgesehen.

Wie die Strategie funktioniert

  1. Eine WMA wird anhand des Basissymbols berechnet, wobei die Länge standardmäßig 200 beträgt.

  2. Wenn die WMA steigt, geh lang, wenn sie fällt, geh kurz.

  3. TakeProfit für Long/Short und StopLoss für Long/Short sind berechnete Prozentsätze, also 0,05 = 5% usw. Auch TakeProfit/StopLoss werden auf dem Basis-Symbol nicht Charts Symbol berechnet.

  4. Die Strategie verwendet Marktaufträge für den Ein- und Ausstieg auf der Grundlage folgender Logik:

    • Wenn die WMA steigt und keine Position besteht, ist ein Long-Entry erforderlich.

    • Wenn die WMA fällt und keine Position besteht, wird ein kurzer Einstieg durchgeführt

    • Wenn Long-Positionsgewinn >= TakeProfitLong-Prozentsatz, Schließung Long

    • Wenn der Gewinn aus der Shortposition >= TakeProfitShort-Prozent ist, schließt der Short

    • Wenn Long-Positionsverlust >= StopLossLong-Prozent, schließen Sie Long

    • Wenn der Verlust einer Short-Position >= StopLossShort-Prozent ist, schließt die Short-Position

  5. Die TakeProfit- und StopLoss-Preise werden in Echtzeit basierend auf den Preisänderungen des Basissymbols aktualisiert.

Analyse der Vorteile

  1. Die Strategie ist sehr anpassungsfähig für die Verwendung auf mehreren Kryptowährungen, indem Parameter angepasst werden.

  2. Die Verwendung des Wall Street CCI zur Bestimmung des Trends vermeidet geräuschgeführte falsche Trades.

  3. Die Einbeziehung von TakeProfit und StopLoss erlaubt es, dem Trend zu folgen und gleichzeitig den Verlust pro Handel zu kontrollieren.

  4. Voll automatisierter Handel ohne manuelles Eingreifen ermöglicht 24/7 Laufzeit.

Risikoanalyse

  1. Risiko einer Entkopplung des Ziel-Kryptopreises von der Basis-Krypto, was zum Scheitern der Strategie führt.

  2. Risiko einer plötzlichen Volatilität, die die Positionen stoppt. Kann StopLoss Prozent anpassen oder Trailing Stops verwenden.

  3. Das Risiko von TakeProfit Prozent zu gering, um ausreichende Trendgewinne zu erfassen.

  4. Risiko eines falschen Ausbruchs, der zu einem Stop-Loss-Ausgang führt.

Optimierungsrichtlinien

  1. Verwenden Sie Korrelationsanalysen über mehrere Basis-Kryptos hinweg und kombinieren Sie Indikatoren, um das Krypto-Risiko mit einer einzigen Basis zu reduzieren.

  2. Hinzufügen von Trendverfolgung zur dynamischen Anpassung von TakeProfit/StopLoss anhand der Volatilität.

  3. Fügen Sie stufenweise Stopps hinzu, um zu verhindern, dass extreme Bewegungen die Positionen stoppen.

  4. Hinzufügen einer Wiedereintrittslogik, um weitere Trends nach dem Stop-Loss-Ausgang nicht zu verpassen.

  5. Optimierung der CCI-Parameter und -Einstellungen zur Verbesserung der Signalleistung.

  6. Optimieren Sie die Parameter separat für jede Ziel-Krypto, um die Anpassungsfähigkeit zu verbessern.

  7. Optimieren Sie die Positionsgröße anhand der Kontogröße.

Zusammenfassung

Insgesamt handelt es sich um eine typische Trendfolgestrategie. Die Kernidee besteht darin, die Trendrichtung einer Benchmark-Krypto unter Verwendung des Wall Street CCI zu bestimmen und die Ziel-Krypto entsprechend zu handeln. Die Strategie hat einige Vorteile, aber auch Risiken zu beachten. Weitere Verbesserungen bei der Abstimmung, Trendverfolgung, Risikokontrolle usw. können die Stabilität und Rentabilität verbessern. Zusammenfassend liefert die Strategie Ideen und Referenzen für den automatisierten systematischen Kryptohandel.


/*backtest
start: 2022-10-25 00:00:00
end: 2023-10-31 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/
// © levieux

//@version=5
strategy(title='Correlation Strategy', shorttitle='Correlation Strategy', initial_capital=1000, overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1)

supportLength = input.int(200, minval=1, title='Support Length')
supportSymbol = input('BTC_USDT:swap', title='Correlated Symbol')
supportSource = input(hlc3, title='Price Source')
takeprofitLong = input.float(0.2, 'Take Profit Long', step=0.01)
takeprofitShort = input.float(0.15, 'Take Profit Short', step=0.01)
stoplossLong = input.float(0.1, 'Stop Loss Long', step=0.01)
stoplossShort = input.float(0.04, 'Stop Loss Short', step=0.01)
start = input(defval = timestamp("01 Jan 2016 00:00 +0000"), title = "Start Time")
end = input(defval = timestamp("31 Dec 2050 23:59 +0000"), title = "End Time")

supportTicker = request.security(supportSymbol, timeframe.period, supportSource, lookahead=barmerge.lookahead_off)  //input(close, title="Source")
supportLine = ta.wma(supportTicker, supportLength)

window() => true

if not window()
    strategy.cancel_all()

supportLongPrice = close
supportShortPrice = close

if strategy.position_size > 0
    supportLongPrice := supportLongPrice[1]
if strategy.position_size < 0
    supportShortPrice := supportShortPrice[1]

longCondition = ta.rising(supportLine, 5) and window() and strategy.position_size <= 0
shortCondition = ta.falling(supportLine, 5) and window() and window() and strategy.position_size > 0
takeprofitLongCondition = takeprofitLong > 0 and window() and strategy.position_size > 0 and supportTicker > supportLongPrice * (1 + takeprofitLong)
stoplossLongCondition = stoplossLong > 0 and window() and strategy.position_size > 0 and supportTicker < supportLongPrice * (1 - stoplossLong)
takeprofitShortCondition = takeprofitShort > 0 and window() and strategy.position_size < 0 and supportTicker > supportShortPrice * (1 + takeprofitShort)
stoplossShortCondition = stoplossShort > 0 and window() and strategy.position_size < 0 and supportTicker < supportShortPrice * (1 - stoplossShort)

if longCondition
    strategy.entry('Long', strategy.long)
    supportLongPrice := supportTicker

if shortCondition
    strategy.entry('Short', strategy.short)
    supportShortPrice := supportTicker

if takeprofitLongCondition
    strategy.close('Long')
if stoplossLongCondition
    strategy.close('Long')
if takeprofitShortCondition
    strategy.close('Short')
if stoplossShortCondition
    strategy.close('Short')

///////////////////
// MONTHLY TABLE //

new_month = month(time) != month(time[1])
new_year  = year(time)  != year(time[1])

eq = strategy.equity

bar_pnl = eq / eq[1] - 1
bar_bh = (close-close[1])/close[1]

cur_month_pnl = 0.0
cur_year_pnl  = 0.0
cur_month_bh = 0.0
cur_year_bh  = 0.0

// Current Monthly P&L
cur_month_pnl := new_month ? 0.0 : 
                 (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1 
cur_month_bh := new_month ? 0.0 : 
                 (1 + cur_month_bh[1]) * (1 + bar_bh) - 1

// Current Yearly P&L
cur_year_pnl := new_year ? 0.0 : 
                 (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1
cur_year_bh := new_year ? 0.0 : 
                 (1 + cur_year_bh[1]) * (1 + bar_bh) - 1

// Arrays to store Yearly and Monthly P&Ls
var month_pnl  = array.new_float(0)
var month_time = array.new_int(0)
var month_bh  = array.new_float(0)

var year_pnl  = array.new_float(0)
var year_time = array.new_int(0)
var year_bh  = array.new_float(0)

end_time = false

end_time:= time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory

if (not na(cur_month_pnl[1]) and (new_month or end_time))
    if (end_time[1])
        array.pop(month_pnl)
        array.pop(month_time)
        
    array.push(month_pnl , cur_month_pnl[1])
    array.push(month_time, time[1])
    array.push(month_bh , cur_month_bh[1])

if (not na(cur_year_pnl[1]) and (new_year or end_time))
    if (end_time[1])
        array.pop(year_pnl)
        array.pop(year_time)
        
    array.push(year_pnl , cur_year_pnl[1])
    array.push(year_time, time[1])
    array.push(year_bh , cur_year_bh[1])

// Monthly P&L Table    
var monthly_table = table(na)

getCellColor(pnl, bh)  => 
    if pnl > 0
        if bh < 0 or pnl > 2 * bh
            color.new(color.green, transp = 20)
        else if pnl > bh
            color.new(color.green, transp = 50)
        else
            color.new(color.green, transp = 80)
    else
        if bh > 0 or pnl < 2 * bh
            color.new(color.red, transp = 20)
        else if pnl < bh
            color.new(color.red, transp = 50)
        else
            color.new(color.red, transp = 80)

if end_time
    monthly_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1)

    table.cell(monthly_table, 0,  0, "",     bgcolor = #cccccc)
    table.cell(monthly_table, 1,  0, "Jan",  bgcolor = #cccccc)
    table.cell(monthly_table, 2,  0, "Feb",  bgcolor = #cccccc)
    table.cell(monthly_table, 3,  0, "Mar",  bgcolor = #cccccc)
    table.cell(monthly_table, 4,  0, "Apr",  bgcolor = #cccccc)
    table.cell(monthly_table, 5,  0, "May",  bgcolor = #cccccc)
    table.cell(monthly_table, 6,  0, "Jun",  bgcolor = #cccccc)
    table.cell(monthly_table, 7,  0, "Jul",  bgcolor = #cccccc)
    table.cell(monthly_table, 8,  0, "Aug",  bgcolor = #cccccc)
    table.cell(monthly_table, 9,  0, "Sep",  bgcolor = #cccccc)
    table.cell(monthly_table, 10, 0, "Oct",  bgcolor = #cccccc)
    table.cell(monthly_table, 11, 0, "Nov",  bgcolor = #cccccc)
    table.cell(monthly_table, 12, 0, "Dec",  bgcolor = #cccccc)
    table.cell(monthly_table, 13, 0, "Year", bgcolor = #999999)


    for yi = 0 to array.size(year_pnl) - 1
        table.cell(monthly_table, 0,  yi + 1, str.tostring(year(array.get(year_time, yi))), bgcolor = #cccccc)
        
        y_color = getCellColor(array.get(year_pnl, yi), array.get(year_bh, yi))
        table.cell(monthly_table, 13, yi + 1, str.tostring(math.round(array.get(year_pnl, yi) * 100)) + " (" + str.tostring(math.round(array.get(year_bh, yi) * 100)) + ")", bgcolor = y_color)
        
    for mi = 0 to array.size(month_time) - 1
        m_row   = year(array.get(month_time, mi))  - year(array.get(year_time, 0)) + 1
        m_col   = month(array.get(month_time, mi)) 
        m_color = getCellColor(array.get(month_pnl, mi), array.get(month_bh, mi))
        
        table.cell(monthly_table, m_col, m_row, str.tostring(math.round(array.get(month_pnl, mi) * 100)) + " (" + str.tostring(math.round(array.get(month_bh, mi) * 100)) +")", bgcolor = m_color)

Mehr