Handelsstrategie zur Umkehrung des Momentum-Breakouts

Schriftsteller:ChaoZhang, Datum: 2023-10-27 17:04:48
Tags:

img

Übersicht

Diese Strategie verwendet einfache gleitende Durchschnitte, um die Trendrichtung zu bestimmen und bei einem Aufwärtstrend lang und bei einem Abwärtstrend kurz zu gehen, um Umkehrhandel zu implementieren.

Strategie Logik

Diese Strategie verwendet den gewichteten gleitenden Durchschnitt (VWMA), um die Markttrendrichtung zu bestimmen.

Die VWMA-Bilanz wird in einem bestimmten Zeitraum berechnet und dann beurteilt, ob die VWMA für mehr als 5 Tage gestiegen ist. Wenn ja, eröffnet sie eine Long-Position. Wenn die VWMA für mehr als 5 Tage gefallen ist, eröffnet sie eine Short-Position. Die Schlusskondition ist, wenn die VWMA-Richtung für mehr als 5 Tage umgekehrt ist.

Um die monatliche und die jährliche Rendite zu berechnen, erfasst die Strategie den Gewinn/Verlust jedes Monats und jedes Jahres.

Analyse der Vorteile

Zu den Vorteilen dieser Strategie gehören:

  1. Die Verwendung von VWMA zur Tendenzbestimmung kann Marktlärm effektiv filtern und wichtige Trends erfassen.

  2. Die Eröffnung einer Position erst nach Bestätigung des Trends kann Risiken einer Trendumkehr vermeiden.

  3. Der Umkehrhandel kann sowohl vom Aufwärtstrend als auch vom Abwärtstrend profitieren.

  4. Die Aufzeichnung der monatlichen und jährlichen Renditen erleichtert die Bewertung der Strategieergebnisse.

  5. Durch das Hinzufügen von Markt-Benchmark-Renditen ist ein direkter Vergleich zwischen Strategie und Markt möglich.

Risikoanalyse

Einige Risiken dieser Strategie:

  1. Die Verwendung von VWMA zur Bestimmung des Trends kann zu Beginn des Trends Verzögerungen und Chancen verpassen.

  2. Eröffnungsposition erst nach Bestätigung kann einige Bewegungen verpassen.

  3. Der Umkehrhandel muss einen Stop-Loss einstellen, sonst könnte sich der Verlust vergrößern.

  4. Eine erhebliche Marktschwankung kann zum Stop-Loss führen und den gesamten Trend nicht halten.

  5. Die Beurteilung der Trendumkehr kann ungenau sein und Verluste vergrößern.

Optimierungsrichtlinien

Einige Aspekte, die die Strategie optimieren könnten:

  1. Optimierung des VWMA-Periodenparameters zur Verbesserung der Trendbestimmung.

  2. Anpassung der Anzahl der Tage zur Bestätigung des Trends, Verbesserung der Ein- und Ausstiegszeit.

  3. Hinzufügen einer Stop-Loss-Strategie zur Kontrolle von Einzelverlusten.

  4. Einbeziehung anderer Indikatoren zur Bestimmung von Umkehrungen, um die Gewissheit zu erhöhen.

  5. Optimierung der Positionsgröße anhand der Marktbedingungen.

  6. Berücksichtigen Sie die Handelskosten, setzen Sie ein Mindestgewinnziel.

Zusammenfassung

Die allgemeine Logik dieser Strategie ist einfach und klar, wobei VWMA verwendet wird, um die Trendrichtung und den Umkehrhandel nach der Bestätigung zu bestimmen, was die Marktbewegungen effektiv verfolgen kann. Aber es birgt auch einige Risiken, die weitere Tests und Parameter-Tuning, Anpassung der Eingangs-/Ausgangslogik und geeignete Positionsgröße erfordern. Diese grundlegende Umkehrhandelsstrategie bildet die Grundlage für den quantitativen Handel und ist eine weitere Forschung und Verbesserung wert.


/*backtest
start: 2023-01-01 00:00:00
end: 2023-10-26 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="Monthly Returns in Strategies with Market Benchmark", shorttitle="Monthly P&L With Market", 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)
maLength= input(400)

wma= vwma(hl2,maLength)
uptrend= rising(wma, 5)
downtrend= falling(wma,5)

plot(wma)

if uptrend
    strategy.entry("Buy", strategy.long)
else
    strategy.close("Buy")//

///////////////////
// 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)

last_computed = false

if (not na(cur_month_pnl[1]) and (new_month or time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory))
    if (last_computed[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 time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory))
    if (last_computed[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])

last_computed := (time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory) ? true : nz(last_computed[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
            color.new(color.red, transp = 20)
        else if pnl < bh
            color.new(color.red, transp = 50)
        else
            color.new(color.red, transp = 80)

if last_computed
    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, 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, tostring(round(array.get(year_pnl, yi) * 100)) + " (" + tostring(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, tostring(round(array.get(month_pnl, mi) * 100)) + " (" + tostring(round(array.get(month_bh, mi) * 100)) +")", bgcolor = m_color)

Mehr