Dynamische Strategie-Analyse-Tool

Schriftsteller:ChaoZhang, Datum: 2023-10-13
Tags:

Übersicht

Die Hauptidee dieser Strategie besteht darin, Echtzeithandel zu simulieren, wöchentliche Handelsdaten zu sammeln und die Statistiken in einer Tabelle für eine intuitivere Überprüfung der Strategie zu präsentieren.

Strategie Logik

  1. Festlegen der Anfangs- und Endzeit des Berechnungszeitraums.

  2. Stellen Sie die Präzision der Statistiken und die Anzahl der Wochen in jeder Gruppe fest.

  3. Simulieren Sie die RSI-Strategie für Ein- und Ausgänge.

  4. Definition von Variablen für die Statistiktabelle.

  5. Berechnen Sie das Ergebnis für den laufenden Zeitraum.

  6. Wenn sich die Periode ändert und der Handel aktiviert ist, werden die Zeit und das Ergebnis für diesen Zeitraum erfasst.

  7. Wenn es sich um den letzten Balken handelt und der Handel aktiviert ist, werden die Zeit und das Ergebnis für den laufenden Zeitraum erfasst.

  8. Wenn sich die Periode ändert und der Handel deaktiviert ist, werden die Zeit und das Ergebnis der vorherigen Periode erfasst.

  9. Finden Sie höchste und niedrigste Periodenergebnisse.

  10. Geben Sie mir die Statistiktabelle.

  • Berechnen Sie zunächst die Gesamtzahl der statistischen Perioden

  • Iteration durch jede Periode, Überschriften, Zeit und Ergebnisse

  • Berechnen Sie das Ergebnis für jede Gruppe kumulativ

  • Farbcodes positive und negative Ergebnisse

Analyse der Vorteile

  • Kann wöchentliche Ergebnisse in Echtzeit für eine schnelle Strategiebewertung beobachten

  • Intuitive Darstellung der Ergebnisse für klare Erkenntnisse

  • Hilfe bei der Ermittlung von Zeiten mit schlechter Leistung für die Anpassung der Strategie

  • Bequem, um kumulative Gewinne für langfristige Strategien zu verfolgen

  • Kann Handelsstile in verschiedenen Zeitabschnitten vergleichen

  • Anpassbare Präzision und Gruppen, um unterschiedlichen Bedürfnissen gerecht zu werden

  • Einfacher und klarer Code, leicht zu verstehen und zu erweitern

Risikoanalyse

  • Die Strategie basiert auf dem RSI, der einen inhärenten Trend nach Einschränkungen aufweist.

  • Handelskosten können sich erheblich auf die tatsächlichen Ergebnisse auswirken

  • Daten aus den Backtests spiegeln möglicherweise nicht die tatsächlichen Marktbedingungen wider

  • Das im Backtest festgelegte Ausfallkapital entspricht möglicherweise nicht der tatsächlichen Kontogröße

  • Vermeiden Sie eine Überanpassung durch blinde Abstimmung von Parametern auf der Grundlage von Statistiken

Kann mehr Indikatoren für den Trend integrieren und Ein- und Ausstiege optimieren, um die grundlegende RSI-Strategie zu verbessern. Verwenden Sie tatsächliche Handelskosten im Live-Handel. Fügen Sie dem Kapitalbetrag im Backtest Zufälligkeit hinzu. Halten Sie Skepsis bei, anstatt auf der Grundlage von Statistiken zu tun.

Optimierungsrichtlinien

  • Erwägen Sie, einen Stop-Loss hinzuzufügen, um den Abwärtstrend zu begrenzen

  • Optimieren Sie RSI-Parameter wie Überkauf- und Überverkaufswerte

  • Versuchen Sie verschiedene Handelsfrequenzen wie Intraday vs. Monats-Holding

  • Mehr Indikatoren für Trends und Zeitpunkte

  • Logik der Gewinnentnahme

  • Optimieren der Einstellungen für statistische Parameter

  • Erweitern, um mehrere Assets zu verfolgen

Stopps können Risiko/Belohnung besser verwalten. RSI-Tuning verbessert die Gewinnrate. Mehr Indikatoren und Frequenzen machen die Strategie robust. Statistisches Tuning hebt wichtige Daten hervor. Die Erweiterung auf mehrere Vermögenswerte gibt einen vollständigen Überblick.

Zusammenfassung

Das Ziel ist es, regelmäßige Ergebnisse für intuitive statistische Visualisierung zu sammeln, um die Leistung zeitlich schnell zu beurteilen. Dies liefert Daten zur Optimierung von Strategien. Zu den Stärken gehören in Echtzeit erstellte wöchentliche Ergebnisse, Klarheit und Erweiterbarkeit.


/*backtest
start: 2023-09-12 00:00:00
end: 2023-10-12 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
// strategy('Strategy weekly results as numbers v1', overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=25, commission_type=strategy.commission.percent, commission_value=0.04)

after = input(title='Trade after', defval=timestamp('01 Jan 2019 00:00 UTC'), tooltip="Strategy will be executed after this timestamp. The statistic table will include only periods after this date.")
before = input(title='Trade before', defval=timestamp('31 Dec 2024 23:59 UTC'), tooltip="Strategy will be executes before this timestamp. The statistic table will include only periods before this date.")

statisticPrecision = input.int(title='Statistic precision', group='Statistic visualisation', defval=1, tooltip="Defines how many digits should be rendered in every statistic cell.")
statisticGroupSize = input.int(title='Statistic group size', group='Statistic visualisation', defval=12, tooltip="Defines how many cells should be in one group inside the statistic table.")

// determinet whether the starategy should be traded between the period
isTradeEnabled = true


// *******************************************************************************************
// Core strategy simulation logic
// *******************************************************************************************
// calculate rsi strategy emulation data
rsiEmulationData = ta.rsi(close, 7)
rsiEmulationCrossover = ta.crossover(rsiEmulationData, 70)
rsiEmulationCrossunder = ta.crossunder(rsiEmulationData, 30)

// entry loogic based on the rsi calculations
if (isTradeEnabled and rsiEmulationCrossover)
    strategy.entry('Long', strategy.long)
if (isTradeEnabled and rsiEmulationCrossunder)
    strategy.entry('Short', strategy.short)


// *******************************************************************************************
// Weekly statistics table
// *******************************************************************************************
// define statistic variables
var statisticTable = table(na)
var statisticPeriodTime = array.new_int(0)
var statisticPeriodResult = array.new_float(0)
var statisticIsLatestCalculated = bool(na)
var statisticResultHighest = float(na)
var statisticResultLowest = float(na)
var statisticColorGray = color.new(color.gray, transp = 60)
var statisticColorGreen = color.new(color.green, transp = 60)
var statisticColorRed = color.new(color.red, transp = 60)

// claculate current period result
barResult = not na(strategy.equity[1])
             ? (strategy.equity / strategy.equity[1] - 1) : 0
isPeriodChanged = not na(time[1]) and weekofyear(time) != weekofyear(time[1])
currentPeriodResult = 0.0
currentPeriodResult := not na(currentPeriodResult[1]) and not isPeriodChanged
                       ? ((1 + currentPeriodResult[1]) * (1 + barResult) - 1) : 0.0

// initialise highest and lowest results variables
statisticResultHighest := na(statisticResultHighest) ? currentPeriodResult : statisticResultHighest
statisticResultLowest := na(statisticResultLowest) ? currentPeriodResult : statisticResultLowest

// search for highest and lowest results
statisticResultHighest := currentPeriodResult > statisticResultHighest ? currentPeriodResult : statisticResultHighest
statisticResultLowest := currentPeriodResult < statisticResultLowest ? currentPeriodResult : statisticResultLowest

// new week while trade is active
if isPeriodChanged and isTradeEnabled
    timeCalculated = time - 1000 * 60 * 60 * 24 * 7
    resultCalculated = currentPeriodResult[1]
    statisticIsLatestCalculated := false

    array.push(statisticPeriodTime, timeCalculated)
    array.push(statisticPeriodResult, resultCalculated)

// latest bar while trade is active
if barstate.islast and isTradeEnabled
    timeCalculated = time - 1000 * 60 * 60 * 24 * (dayofweek(time) - 2)
    resultCalculated = currentPeriodResult

    array.push(statisticPeriodTime, timeCalculated)
    array.push(statisticPeriodResult, resultCalculated)

// new week after trade disabled
if isPeriodChanged and not isTradeEnabled and not na(statisticIsLatestCalculated) and not statisticIsLatestCalculated
    timeCalculated = time - 1000 * 60 * 60 * 24 * (dayofweek(time) + 5)
    resultCalculated = currentPeriodResult[1]
    statisticIsLatestCalculated := true

    array.push(statisticPeriodTime, timeCalculated)
    array.push(statisticPeriodResult, resultCalculated)

// render statistics table
if barstate.islast
    statisticLength = array.size(statisticPeriodResult)
    statisticTableSteps = math.floor(statisticLength / statisticGroupSize) + (statisticLength % statisticGroupSize != 0 ? 1 : 0)
    statisticTable := table.new(position.bottom_right, columns = statisticGroupSize + 2, rows = statisticTableSteps + 1, border_width = 1)

    // render headers
    for i = 0 to (statisticGroupSize - 1)
        statisticHeaderContent = str.tostring(i + 1)
        table.cell(statisticTable, 1 + i, 0, statisticHeaderContent, bgcolor = statisticColorGray)

    // render time points
    for i = 0 to (statisticTableSteps - 1)
        statisticPointContent = str.format("{0,date,medium}", array.get(statisticPeriodTime, i * statisticGroupSize))
        table.cell(statisticTable, 0, 1 + i, statisticPointContent, bgcolor = statisticColorGray)

    // render the result
    statisticResultCummulative = 0.0
    for i = 0 to (array.size(statisticPeriodTime) - 1)
        statisticColumn = 1 + i % statisticGroupSize
        statisticRow = 1 + math.floor(i / statisticGroupSize)

        statisticResult = array.get(statisticPeriodResult, i)
        statisticResultCummulative := (i % statisticGroupSize == 0) ? 0.0 : statisticResultCummulative
        statisticResultCummulative := (1 + statisticResultCummulative) * (1 + statisticResult) - 1

        statisticResultColor = statisticResult > 0 ? statisticColorGreen : statisticColorRed
        table.cell(statisticTable, statisticColumn, statisticRow, str.tostring(math.round(statisticResult * 100, statisticPrecision)), bgcolor = statisticResultColor)

        // if it is the last item of the row or data array
        isStatisticLastOfTheRow = ((i + 1) % statisticGroupSize) == 0
        isStatisticLastOfTheData = i == (statisticLength - 1)
        if (isStatisticLastOfTheRow or isStatisticLastOfTheData)
            resultsTableCummulativeCellColor = statisticResultCummulative > 0 ? statisticColorGreen : statisticColorRed
            resultsTableCummulativeCellContent = str.tostring(math.round(statisticResultCummulative * 100, statisticPrecision))
            table.cell(statisticTable, 1 + statisticGroupSize, statisticRow, resultsTableCummulativeCellContent, bgcolor = resultsTableCummulativeCellColor)

Mehr