Super Trend MACD Quantitative Strategie


Erstellungsdatum: 2023-12-26 11:13:24 zuletzt geändert: 2023-12-26 11:13:24
Kopie: 0 Klicks: 792
1
konzentrieren Sie sich auf
1621
Anhänger

Super Trend MACD Quantitative Strategie

Überblick

Die Strategie nutzt die potentiellen Trendwende-Signale der Übertrend- und MACD-Indikatoren in Kombination mit den Überkauf- und Überverkauf-Signale des RSI-Indikators zu einem stabileren und effizienteren Signalsystem für die Eröffnung und Schließung von Positionen. Die Strategie wird als Quantifizierung der Übertrend-MACD-Strategie bezeichnet.

Strategieprinzip

Die Kernlogik der Strategie besteht darin, dass die Übertrendindikatoren und die MACD-Indikatoren als Kriterien für Positionsöffnungssignale verwendet werden.

Im Übertrend-Bereich verwendet die Strategie die Änderung der Richtung des Übertrend-Indikators als potenzielles Umkehrsignal. Es erzeugt ein Kaufsignal, wenn die Richtung des Übertrend-Indikators von oben nach unten wechselt; Es erzeugt ein Verkaufsignal, wenn die Richtung des Übertrend-Indikators von unten nach oben wechselt.

Der MACD-Teil verwendet die Schräglage und die Null-Achs-Kreuzung des MACD-Indikators auf einem niedrigeren Zeitrahmen (die Tageslinie) zur Beurteilung der potenziellen Umkehrchancen. Es erzeugt ein Signal, wenn die MACD-Schräglage größer als der absolute Wert (größer als der Schwellenwert) ist und die Schräglage steigt; es erzeugt auch ein Hilfssignal, wenn der MACD-Indikator die Null-Achs kreuzt.

Die Strategie erfordert, dass die Übertrendsignale und die MACD-Signale in der gleichen Richtung sind, um die Position zu eröffnen.

Darüber hinaus wurde ein Überkauf-Überverkauf-Signal für den RSI-Indikator eingeführt. Wenn der RSI-Indikator größer als 80 ist, wird ein Verkaufssignal erzeugt, wenn er kleiner als 20 ist, wird ein Kaufsignal erzeugt, um zu helfen, den Zeitpunkt der Umkehrung zu bestimmen.

Analyse der Stärken

Der größte Vorteil dieser Strategie liegt in der Vielfalt der Indikatorensignale. Die verschiedenen Indikatoren können sich ergänzen und das Gesamtsignal stabiler und zuverlässiger machen.

Der MACD-Schrägpunkt kann die Stärke des mittelfristigen Trends bestimmen und verhindert, dass er von einer falschen Umkehr abgeleitet wird, während der RSI den besten Zeitpunkt für den Auftakt und die beste Position für den Überverkauf von Überkäufern in Zwischenraum-Schocks anzeigt. Die Überlagerung mehrerer Indikatorsignale filtert einige der lauten Geschäfte ab und erzielt eine höhere Gewinnrate.

Darüber hinaus ist der Zeitrahmen der Strategie relativ vernünftig eingestellt. Der Hypertrend verwendet einen Stunden-Zeitrahmen, der MACD-Indikator verwendet die Tageslinie, um die Handelsfrequenz zu gewährleisten und die Stabilität der Trendurteile zu berücksichtigen.

Risikoanalyse

Das Hauptrisiko dieser Strategie besteht darin, dass es eine hohe Wahrscheinlichkeit gibt, dass ein Mischsignal zwischen den Indikatoren erzeugt wird. Zum Beispiel, dass ein Hypertrend eine falsche Umkehrung erzeugt, während das MACD-Signal nicht synchron erzeugt wird. Dies kann zu unnötigen Verlusten führen.

Darüber hinaus kann der RSI zu früh oder zu spät für die Feststellung einer Position eingesetzt werden, so dass die Haltedauer der Strategie nicht maximiert wird.

Schließlich kann eine zu hohe Schrägstörung des MACD auch dazu führen, dass schwache Umkehrmöglichkeiten verpasst werden.

Optimierungsrichtung

Die Strategie kann in folgenden Bereichen weiter optimiert werden:

  1. Die Einführung eines Stop-Loss-Mechanismus.

  2. Die Beurteilung der MACD-Schräglage umfasst die Hinzufügung von dynamischen Abschwächungen. Die Schräglage wird erhöht, wenn die Marktfluktuation groß ist, und die Abschwächung wird bei Marktstabilität gesenkt.

  3. Die RSI-Indikator-Bleichstellung wird mit einer Rückstellungsvoraussetzung beurteilt. Nach einer deutlichen Rückstellung über 80 wird die Bleibigkeit berücksichtigt.

  4. Testing MACD with volume and see if it improves signal reliability

  5. Trying automated parameter tuning to find optimal settings

Zusammenfassen

Die Übertrend-MACD-Quantifizierungsstrategie kombiniert mehrere Indikatoren, um ein Signal für eine Position zu eröffnen und eine Position zu halten. Die Vorteile sind die Signalstabilität, die hohe Gewinnrate, die durch Parameteroptimierung weiter verbessert werden kann. Die Risiko- und Optimierungsrichtung konzentriert sich auch hauptsächlich auf die Frage der Parameterüberfitting.

Strategiequellcode
/*backtest
start: 2022-12-19 00:00:00
end: 2023-12-25 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5

strategy("SuperTrend.MACD Strategy", overlay=false, default_qty_type=strategy.percent_of_equity, default_qty_value=100, initial_capital=100000, pyramiding=5, process_orders_on_close=true)

// ---------------- Utility Functions ----------------
getArrayValue(float[] arr, int ago) =>
    if ago >= 0
        array.get(arr, ago >= array.size(arr) ? na: array.size(arr) + -1 * ago -1)
    else
        na

filterNA(float[] a, s, int y) =>
    int x = 0
    if not na(s[0])
        array.push(a, s[0])
        if array.size(a) > y
            array.shift(a)
    a

pine_rsi(float[] x, int y) =>
    x0 = getArrayValue(x, 0)
    x1 = getArrayValue(x, 1)

    u = math.max(x0 - x1, 0) // upward ta.change
    d = math.max(x1 - x0, 0) // downward ta.change
    rs = ta.rma(u, y) / ta.rma(d, y)
    res = 100 - 100 / (1 + rs)
    res

turnAround(float[] arr) =>
    int isTurnAround = 0
    
    now = getArrayValue(arr, 0)
    p1 = getArrayValue(arr, 1)
    p2 = getArrayValue(arr, 2)

    if p1 > now and p1 > p2
        isTurnAround := -1
    else if p1 < now and p1 < p2
        isTurnAround := 1

intergerizeSignal(i) =>
    i>0 ? 1 : i<0 ? -1 : 0

linreg(float[] y, int n, int offset=0) => 
    float slope = na
    float intercept = na

    int endcursor = offset + n - 1

    if array.size(y) > endcursor
        float sumX = 0
        float sumX2 = 0
        float sumY = 0
        float sumY2 = 0
        float sumXY = 0

        for i=offset to endcursor
            yv = array.get(y, i)
            sumY += yv
            sumY2 += math.pow(yv, 2)
            sumX += i
            sumX2 += math.pow(i, 2)
            sumXY += i*yv

        // Pearson correlation coefficient
        r = (n * sumXY - sumX * sumY) / math.sqrt((n * sumY2 - math.pow(sumY, 2)) * (n * sumX2 - math.pow(sumX, 2)))

        // Coefficient of determination
        r2 = math.pow(r, 2)

        meanX = sumX / n
        meanY = sumY / n

        slope := (n * sumXY - sumX * sumY) / (n * sumX2 - math.pow(sumX, 2))
        intercept := meanY - slope * meanX

    [slope, intercept]

isStartOfDay() => dayofweek != dayofweek[1]

// ---------------- Variables ----------------

varip float st_signal = 0
varip float macd_signal = 0
varip float macd_close_signal = 0
varip float histo_signal = 0

var int openSignal = 0
var int closeSignal = 0

// -------------------------------- Supertrend Signal (Open) --------------------------------

// ST calculation
atrPeriod = input(10, "Supertrend ATR Length")
factor = input.float(2.0, "Supertrend Factor", step = 0.01)

[_, direction] = ta.supertrend(factor, atrPeriod)

st_direction_change = ta.change(direction)
if st_direction_change < 0
    st_signal := 4
if st_direction_change > 0
    st_signal := -4

// -------------------------------- MACD Signal (Open + Close) --------------------------------

// MACD Calculation
fastLength = input(12, title="MACD Fast Length")
slowLength = input(26, title="MACD Slow Length")
signalLength = input(9, title="MACD Signal Length")
macdSlowTimeframe = input.timeframe("D", "MACD Timeframe")
macdSlopeLookbackOpen = input(7, title="MACD Slope Lookback - Open")
macdSlopeLookbackClose = input(3, title="MACD Slope Lookback - Close")

dailyClose = request.security(syminfo.tickerid, macdSlowTimeframe, close, barmerge.gaps_on)
[macdLine, signalLine, _] = ta.macd(dailyClose, fastLength, slowLength, signalLength)

// MACD Slope calculation

varip macdHistory = array.new<float>(0)
varip macdSlowSlopeArr = array.new<float>(0)
varip float macdSlowSlope = na
varip float macdCloseSlope = na

if not na(macdLine[0])
    array.push(macdHistory, macdLine[0])
    if array.size(macdHistory) > macdSlopeLookbackOpen
        array.shift(macdHistory)
    [s1, _] = linreg(macdHistory, macdSlopeLookbackOpen)
    macdSlowSlope := s1

    array.push(macdSlowSlopeArr, macdSlowSlope)
    if array.size(macdSlowSlopeArr) > macdSlopeLookbackClose
        array.shift(macdSlowSlopeArr)
    [s2, _] = linreg(macdSlowSlopeArr, macdSlopeLookbackClose)
    macdCloseSlope := s2

// MACD Signal Calculation
// > open signal
threshold_macdSlowSlope = input.float(0.75, "MACD Slope Open Threshold", step = 0.05)

macdSlowSlopeOverThreshold = math.abs(macdSlowSlope) >= threshold_macdSlowSlope
macdSlowSlopeTrend = macdSlowSlope - getArrayValue(macdSlowSlopeArr, 1)
macdSlowSlopeTrendConfirm = macdSlowSlope*macdSlowSlopeTrend >0

if (macdSlowSlopeOverThreshold and macdSlowSlopeTrendConfirm)
    macd_signal := 3*macdSlowSlope/math.abs(macdSlowSlope)
else
    macd_signal := 0

// > close signal
int macdCloseSignal = 0
macdCloseSignal := intergerizeSignal(macdCloseSlope)

// Histogram signal Calculation
histSlow = macdLine - signalLine

if (ta.crossover(histSlow, 0))
	histo_signal := 2
if (ta.crossunder(histSlow, 0))
	histo_signal := -2

// -------------------------------- RSI Signal (Close) --------------------------------
int rsiCloseSignal = 0
varip float rsiSlow = na

rsiPeriod = input(14, title="RSI Period")

varip dailyCloseRSIFilter = array.new_float()

// rewrite pine_rsi to remove NaN value from series at calculation
dailyCloseRSIFilter := filterNA(dailyCloseRSIFilter, dailyClose, rsiPeriod)

if not na(dailyClose[0])
    rsiSlow := pine_rsi(dailyCloseRSIFilter, rsiPeriod)

if rsiSlow > 80
    rsiCloseSignal := -1
else if rsiSlow < 20
    rsiCloseSignal := 1
else
    rsiCloseSignal := 0

// -------------------------------- Overall Signal --------------------------------

// Close signal
closeSignals = array.from(macdCloseSignal, rsiCloseSignal)
closeSignal := array.includes(closeSignals, 1) ? 1 : array.includes(closeSignals, -1) ? -1 : 0
closeSignal := closeSignal * 5

// Open signal
if (macd_signal * st_signal > 0) and (macd_signal * macd_close_signal >= 0)
    openSignal := intergerizeSignal(st_signal)
    openSignal := openSignal * 6
else
    openSignal := 0

// -------------------------------- Order --------------------------------
// if strategy.position_size == 0
if openSignal * closeSignal >=0
    if openSignal > 0
        strategy.entry("Long Entry", strategy.long)
    else if openSignal < 0
        strategy.entry("Short Entry", strategy.short)

if strategy.position_size != 0
    if closeSignal < 0
        strategy.close("Long Entry")
    if closeSignal > 0
        strategy.close("Short Entry")


// -------------------------------- Plot --------------------------------

plot(closeSignal, title="Close Signal", color=color.red, linewidth = 1, style=plot.style_area)
plot(openSignal, title="Open Signal", color=color.green, linewidth = 1, style=plot.style_area)
plot(st_signal, title="ST Signal", color=color.black, linewidth = 1, style=plot.style_circles)
plot(macd_signal, title="MACD Signal", color=color.blue, linewidth = 1, style=plot.style_circles)
// plot(macdSlowSlope, title="macd slow slope", color=color.purple, linewidth = 1, style=plot.style_line)
// plot(macdCloseSlope, title="macd slow slope", color=color.lime, linewidth = 1, style=plot.style_line)

hline(0, "Zero Line", color=color.gray)