Diese Strategie verwendet ein gleitendes Durchschnittssystem, um die aktuelle Trendrichtung zu bestimmen, und macht Long- oder Short-Positionen entsprechend dem Trend. Wenn der gleitende Durchschnitt steigt, ist das Vertrauen in Long höher, also gehen Sie lang. Wenn der gleitende Durchschnitt sinkt, ist das Vertrauen in Short höher, also gehen Sie kurz. Diese Strategie verwendet hauptsächlich das gleitende Durchschnittssystem, um die Markttrendrichtung zu bestimmen, die zur Trendfolgestrategie gehört.
Der gewichtete gleitende Durchschnitt vwma wird als gleitender Durchschnittsindikator für einen bestimmten Zeitraum berechnet (Standard 400 Perioden).
Bestimmen Sie, ob der gleitende Durchschnitt vwma steigt, wenn steigt, setzen Sie den langen Signal-Aufwärtstrend ein; wenn er fällt, setzen Sie den kurzen Signal-Abwärtstrend ein.
Wenn der Aufwärtstrend wahr ist, gehen Sie lang; wenn der Abwärtstrend wahr ist, schließen Sie lang und gehen Sie kurz.
Berechnen Sie die Strategie return bar_pnl und buy & hold return bar_bh für jeden Balken.
Nach den vierteljährlichen und jährlichen Zeitstempeln berechnen Sie die vierteljährliche Strategierendite quarter_pnl, die jährliche Rendite year_pnl und die entsprechenden Buy & Hold Renditen quarter_bh, year_bh.
Die vierteljährliche Strategierendite gegenüber der Buy & Hold Rendite in einer Tabelle anzeigen.
Die wichtigsten Vorteile dieser Strategie sind:
Einfache Bedienung, leicht verständliche Bestimmung der Marktentwicklung durch gleitende Durchschnitte.
Der Trend zu folgen reduziert Verluste auf nicht-trendigen Märkten.
Wenige einstellbare Parameter, hauptsächlich die Periode des gleitenden Durchschnitts, leicht zu testen und zu optimieren.
Intuitive Rücklauftabelle, um die Ergebnisse deutlich zu zeigen.
Hinzufügen der Buy & Hold Rendite in der Tabelle zum Vergleich, zeigt die überschüssige Rendite.
Flexible Tischposition, leicht mit anderen Strategien zu integrieren.
Es gibt auch einige Risiken:
Unterleistung im langfristigen Bullenmarkt im Vergleich zu Buy & Hold. Kann die gleitende Durchschnittsperiode optimieren.
Ein hohes Whipsaw-Risiko im Range-bound Markt kann Filterbedingungen hinzufügen, wie das Brechen des vorherigen Hochs, um Transaktionen zu reduzieren.
Der gleitende Durchschnitt hat eine schlechte Fähigkeit zur Kurvenanpassung, kann Trendwendepunkte verpassen.
Es gibt keinen Stop-Loss-Mechanismus, es besteht ein hohes Risiko für einen Rückzug.
Für die Tabelle kann man Risikometriken wie Sharpe Ratio, Max Drawdown hinzufügen.
Die Strategie kann in folgenden Aspekten optimiert werden:
Optimierung der gleitenden Durchschnittsparameter, Anpassung der Periode anhand der Marktregeln.
Fügen Sie Filter hinzu, wie das vorherige Hoch zu brechen, um Whipsaws zu reduzieren.
Versuchen Sie verschiedene Arten von gleitenden Durchschnitten, wie WMA, DEMA usw.
Fügen Sie Stop-Loss-Mechanismen hinzu, wie dynamische Stopps oder Positionsgrößen.
Die Tabelleninhalte bereichern, Metriken wie Schärfe, maximale Auslastung hinzufügen.
Kombinieren Sie mit anderen Indikatoren wie MACD, Bollinger Bands, um Trends zu bestimmen.
Optimierung der Positionsgröße, dynamische Anpassung der Positionen anhand der Marktbedingungen.
Versuche mit verschiedenen Produkten, finde den besten Anwendungsbereich.
Die gleitende Durchschnittshandelsstrategie ist relativ einfach und unkompliziert. Sie folgt dem Trend, indem sie den Trend mit einem gleitenden Durchschnittswert bestimmt, mit guter Ziehkontrolle, geeignet für Trend-nachfolgende Händler. Es gibt immer noch viel Raum für Optimierungen, wie das gleitende Durchschnittssystem, Stop-Loss-Mechanismus, Positionsgröße usw., um es an komplexe Marktumgebungen anzupassen. Das Tabellendesign vergleicht die Strategierendite mit Buy & Hold und zeigt die überschüssigen Renditen intuitiv. Der Rahmen und das Tabellendesign dieser Strategie können für quantitative Händler eine gute Referenz bieten.
/*backtest start: 2022-10-23 00:00:00 end: 2023-10-29 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/ // © Dannnnnnny //@version=4 strategy(title="Quarterly Returns in Strategies vs Buy & Hold", 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")// /////////////////// // QUARTERLY TABLE // enableQuarterlyTable = input(title="Enable Quarterly Return table", type=input.bool, defval=false) enableCompareWithMarket = input(title="Compare with Market Benchmark", type=input.bool, defval=false) table_position = input(title="Table Position", type=input.string, defval='bottom_right', options=['bottom_right','bottom_left','top_right', 'top_left']) precision = 2 new_quarter = ceil(month(time)/3) != ceil(month(time[1])/3) new_year = year(time) != year(time[1]) eq = strategy.equity bar_pnl = eq / eq[1] - 1 bar_bh = (close-close[1])/close[1] cur_quarter_pnl = 0.0 cur_year_pnl = 0.0 cur_quarter_bh = 0.0 cur_year_bh = 0.0 // Current Quarterly P&L cur_quarter_pnl := new_quarter ? 0.0 : (1 + cur_quarter_pnl[1]) * (1 + bar_pnl) - 1 cur_quarter_bh := new_quarter ? 0.0 : (1 + cur_quarter_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 Quarterly P&Ls var quarter_pnl = array.new_float(0) var quarter_time = array.new_int(0) var quarter_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_quarter_pnl[1]) and (new_quarter or end_time)) if (end_time[1]) array.pop(quarter_pnl) array.pop(quarter_time) array.push(quarter_pnl , cur_quarter_pnl[1]) array.push(quarter_time, time[1]) array.push(quarter_bh , cur_quarter_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]) // Quarterly P&L Table var quarterly_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 and enableQuarterlyTable) quarterly_table := table.new(table_position, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1) table.cell(quarterly_table, 0, 0, "", bgcolor = #cccccc) table.cell(quarterly_table, 1, 0, "Q1", bgcolor = #cccccc) table.cell(quarterly_table, 2, 0, "Q2", bgcolor = #cccccc) table.cell(quarterly_table, 3, 0, "Q3", bgcolor = #cccccc) table.cell(quarterly_table, 4, 0, "Q4", bgcolor = #cccccc) table.cell(quarterly_table, 5, 0, "Year", bgcolor = #999999) for yi = 0 to array.size(year_pnl) - 1 table.cell(quarterly_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(quarterly_table, 5, yi + 1, enableCompareWithMarket ? tostring(round(array.get(year_pnl, yi) * 100, precision)) + " (" + tostring(round(array.get(year_bh, yi) * 100, precision)) + ")" : tostring(round(array.get(year_pnl, yi) * 100, precision)), bgcolor = y_color, text_color=#bfbfbf) for mi = 0 to array.size(quarter_time) - 1 m_row = year(array.get(quarter_time, mi)) - year(array.get(year_time, 0)) + 1 m_col = ceil(month(array.get(quarter_time, mi)) / 3) m_color = getCellColor(array.get(quarter_pnl, mi), array.get(quarter_bh, mi)) table.cell(quarterly_table, m_col, m_row, enableCompareWithMarket ? tostring(round(array.get(quarter_pnl, mi) * 100, precision)) + " (" + tostring(round(array.get(quarter_bh, mi) * 100,precision)) +")" : tostring(round(array.get(quarter_pnl, mi) * 100, precision)), bgcolor = m_color, text_color=#bfbfbf)