Handelsstrategie für den Regenbogen-Oszillator

Schriftsteller:ChaoZhang, Datum: 2024-02-23 14:57:43
Tags:

img

Übersicht

Die Rainbow Oscillator-Handelsstrategie verwendet hauptsächlich mehrere glättete gleitende Durchschnitte und Schwingungsindikatoren, um einen mehrschichtigen Schwingungskanal zu erstellen und klare Long/Short-Signale zu erzeugen.

Grundsätze

  1. Berechnen Sie den gewichteten Durchschnitt von RSI, CCI und Stochastic, um einen kombinierten Schwingungsindikator namens Magic zu erstellen;
  2. Wird eine exponentielle Glättung auf Magic mehrmals angewendet, um zwei Linien zu erzeugen, die sampledMagicFast und sampledMagicSlow genannt werden;
  3. SampledMagicFast stellt die schnelle EMA-Linie dar, sampledMagicSlow stellt die langsame EMA-Linie dar;
  4. Ein Kaufsignal wird erzeugt, wenn sampleledMagicFast über sampleledMagicSlow kreuzt;
  5. Ein Verkaufssignal wird erzeugt, wenn die SampledMagicFast unter der SampledMagicSlow kreuzt;
  6. Berechnen Sie die Richtung der letzten Stichbänder, die bei MagicFast gezeigt wurden, im Verhältnis zur vorherigen Stichbänder, um den aktuellen Trend zu bestimmen.
  7. Bestimmung der Ein- und Ausstiegspunkte auf der Grundlage der Trendrichtung und der Kreuzung zwischen den Proben MagicFast und MagicSlow.

Vorteile

  1. Die Kombination mehrerer Indikatoren zur Ermittlung der allgemeinen Marktentwicklung verbessert die Signalgenauigkeit.
  2. Die glatte MA filtert den Lärm effektiv aus.
  3. Mehrschichtliche Schwingungssignale liefern eine klare Betriebsanleitung;
  4. kann so konfiguriert werden, dass der Trendfilter aktiviert/deaktiviert wird, um dem Trend zu folgen oder den Durchschnitt umzukehren;
  5. Anpassbare Überkauf-/Überverkaufstärke für Flexibilität.

Risiken

  1. Überglättete Kurven können zu fehlenden besten Einstiegspunkten führen.
  2. Eine falsche Einstellung des Überkauf-/Überverkaufsbereichs kann dazu führen, dass die Position zu lange geschlossen bleibt;
  3. Ein Ausfall einiger Faktoren im Ratingmodell kann die Signale schwächen.

Lösungen:

  1. Optimierung der Parameter für einen angemessenen Glättungsgrad;
  2. Anpassung der Überkauf-/Überverkaufsflächenstärke, um die Zeit in flacher Position zu verkürzen;
  3. Jeder Indikator wird mit seiner Vorhersagefähigkeit getestet und gewichtet.

Optimierungsrichtlinien

  1. Dynamische Anpassung der Indikatorparameter anhand der Marktbedingungen;
  2. Einführung von Methoden des maschinellen Lernens zur automatischen Optimierung von Indikatorenkombinationen;
  3. Fügen Sie Faktoren wie Volumen- und Volatilitätsfilter zu den Eingangssignalen hinzu.

Schlussfolgerung

Der Regenbogen-Oszillator-Strategie kombiniert Signale aus mehreren Indikatoren und verwendet exponentielle Glättung zur Verbesserung der Stabilität. Es kann sowohl für Trend- als auch für seitliche Märkte oder für bestimmte Produkte konfiguriert werden. Weitere Verbesserungen können durch Parameter-Tuning und Indikator-Erweiterung vorgenommen werden. Insgesamt ist dies eine klare, einfach zu bedienende Strategie.


// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © businessduck

//@version=5
strategy("Rainbow Oscillator [Strategy]", overlay=false, margin_long=100, margin_short=100, initial_capital = 2000)

bool trendFilter = input.bool(true, 'Use trend filter')
float w1 = input.float(0.33, 'RSI Weight', 0, 1, 0.01)
float w2 = input.float(0.33, 'CCI Weight', 0, 1, 0.01)
float w3 = input.float(0.33, 'Stoch Weight', 0, 1, 0.01)
int fastPeriod = input.int(16, 'Ocillograph Fast Period', 4, 60, 1)
int slowPeriod = input.int(22, 'Ocillograph Slow Period', 4, 60, 1)
int oscillographSamplePeriod = input.int(8, 'Oscillograph Samples Period', 1, 30, 1)
int oscillographSamplesCount = input.int(2, 'Oscillograph Samples Count', 0, 4, 1)
string oscillographMAType = input.string("RMA", "Oscillograph Samples Type", options = ["EMA", "SMA", "RMA", "WMA"])
int levelPeriod = input.int(26, 'Level Period', 2, 100)
int levelOffset = input.int(0, 'Level Offset', 0, 200, 10)
float redunant = input.float(0.5, 'Level Redunant', 0, 1, 0.01)
int levelSampleCount = input.int(2, 'Level Smooth Samples', 0, 4, 1)
string levelType = input.string("RMA", "Level MA type", options = ["EMA", "SMA", "RMA", "WMA"])

perc(current, prev) => ((current - prev) / prev) * 100

smooth(value, type, period) =>
    float ma = switch type
        "EMA" => ta.ema(value, period)
        "SMA" => ta.sma(value, period)
        "RMA" => ta.rma(value, period)
        "WMA" => ta.wma(value, period)
        =>
            runtime.error("No matching MA type found.")
            float(na)

getSample(value, samples, type, period) =>
    float ma = switch samples
        0 => value
        1 => smooth(value, type, period)
        2 => smooth(smooth(value, type, period), type, period)
        3 => smooth(smooth(smooth(value, type, period), type, period), type, period)
        4 => smooth(smooth(smooth(smooth(value, type, period), type, period), type, period), type, period)

float takeProfit = input.float(5, "% Take profit", 0.8, 100, step = 0.1)  / 100
float stopLoss = input.float(2, "% Stop Loss", 0.8, 100, step = 0.1) / 100
float magicFast = w2 * ta.cci(close, fastPeriod) + w1 * (ta.rsi(close, fastPeriod) - 50) + w3 * (ta.stoch(close, high, low, fastPeriod) - 50)
float magicSlow = w2 * ta.cci(close, slowPeriod) + w1 * (ta.rsi(close, slowPeriod) - 50) + w3 * (ta.stoch(close, high, low, slowPeriod) - 50)
float sampledMagicFast = getSample(magicFast, oscillographSamplesCount, oscillographMAType, oscillographSamplePeriod)
float sampledMagicSlow = getSample(magicSlow, oscillographSamplesCount, oscillographMAType, oscillographSamplePeriod)
float lastUpperValue = 0
float lastLowerValue = 0

if (magicFast > 0)
    lastUpperValue := math.max(magicFast, magicFast[1])
else 
    lastUpperValue := math.max(0, lastUpperValue[1]) * redunant

    
if (magicFast <= 0)
    lastLowerValue := math.min(magicFast, magicFast[1])
else
    lastLowerValue := math.min(0, lastLowerValue[1]) * redunant

float level1up = getSample( (magicFast >= 0 ? magicFast : lastUpperValue) / 4, levelSampleCount, levelType, levelPeriod) + levelOffset
float level2up = getSample( (magicFast >= 0 ? magicFast : lastUpperValue) / 2, levelSampleCount, levelType, levelPeriod) + levelOffset
float level3up = getSample( magicFast >= 0 ? magicFast : lastUpperValue, levelSampleCount, levelType, levelPeriod) + levelOffset
float level4up = getSample( (magicFast >= 0 ? magicFast : lastUpperValue) * 2, levelSampleCount, levelType, levelPeriod) + levelOffset

float level1low = getSample( (magicFast <= 0 ? magicFast : lastLowerValue) / 4, levelSampleCount, levelType, levelPeriod) - levelOffset
float level2low = getSample( (magicFast <= 0 ? magicFast : lastLowerValue) / 2, levelSampleCount, levelType, levelPeriod) - levelOffset
float level3low = getSample( magicFast <= 0 ? magicFast : lastLowerValue, levelSampleCount, levelType, levelPeriod) - levelOffset
float level4low = getSample( (magicFast <= 0 ? magicFast : lastLowerValue) * 2, levelSampleCount, levelType, levelPeriod) - levelOffset

var transparent = color.new(color.white, 100)
var overbough4Color = color.new(color.red, 75)
var overbough3Color = color.new(color.orange, 75)
var overbough2Color = color.new(color.yellow, 75)

var oversold4Color = color.new(color.teal, 75)
var oversold3Color = color.new(color.blue, 75)
var oversold2Color = color.new(color.aqua, 85)

upperPlotId1 = plot(level1up, 'Upper1', transparent)
upperPlotId2 = plot(level2up, 'Upper2', transparent)
upperPlotId3 = plot(level3up, 'Upper3', transparent)
upperPlotId4 = plot(level4up, 'Upper4', transparent)

fastColor = color.new(color.teal, 60)
slowColor = color.new(color.red, 60)
fastPlotId = plot(sampledMagicFast, 'fast', color = fastColor)
slowPlotId = plot(sampledMagicSlow, 'slow', color = slowColor)

lowerPlotId1 = plot(level1low, 'Lower1', transparent)
lowerPlotId2 = plot(level2low, 'Lower2', transparent)
lowerPlotId3 = plot(level3low, 'Lower3', transparent)
lowerPlotId4 = plot(level4low, 'Lower4', transparent)

fill(upperPlotId4, upperPlotId3, overbough4Color)
fill(upperPlotId3, upperPlotId2, overbough3Color)
fill(upperPlotId2, upperPlotId1, overbough2Color)

fill(lowerPlotId4, lowerPlotId3, oversold4Color)
fill(lowerPlotId3, lowerPlotId2, oversold3Color)
fill(lowerPlotId2, lowerPlotId1, oversold2Color)

upTrend = sampledMagicFast > sampledMagicFast[1]
buySignal = ((upTrend or not trendFilter) and ta.crossunder(sampledMagicSlow, sampledMagicFast)) ? sampledMagicSlow : na
sellSignal = ((not upTrend or not trendFilter) and ta.crossover(sampledMagicSlow, sampledMagicFast)) ? sampledMagicSlow : na
diff = sampledMagicSlow - sampledMagicFast

fill(fastPlotId, slowPlotId, upTrend ? fastColor : slowColor)
plot(buySignal, color = color.aqua, style = plot.style_circles, linewidth = 4)
plot(sellSignal, color = color.red, style = plot.style_circles, linewidth = 4)


// longCondition = upTrend != upTrend[1] and upTrend
long_take_level = strategy.position_avg_price * (1 + takeProfit)
long_stop_level = strategy.position_avg_price * (1 - stopLoss)

short_take_level = strategy.position_avg_price * (1 - takeProfit)
short_stop_level = strategy.position_avg_price * (1 + stopLoss)

strategy.close(id="Long", when=sellSignal, comment = "Exit")
strategy.close(id="Short", when=buySignal, comment = "Exit")

strategy.entry("Long", strategy.long, when=buySignal)
strategy.entry("Short", strategy.short, when=sellSignal)

strategy.exit("Take Profit/ Stop Loss","Long", stop=long_stop_level, limit=long_take_level)
strategy.exit("Take Profit/ Stop Loss","Short", stop=short_stop_level, limit=short_take_level)


// plot(long_stop_level, color=color.red, overlay=true)
// plot(long_take_level, color=color.green)


Mehr