Dieser Artikel erklärt hauptsächlich eine Dynamik-Oszillations-Handelsstrategie, die auf dem Stochastischen RSI-Indikator basiert. Die Strategie verwendet kürzere Zyklus-Technische Indikatoren (z. B. 30 Minuten), um Handelsentscheidungen zu treffen, je nachdem, ob der Stochastische RSI in die Überkauf/Überverkaufsregion eintritt. Im Vergleich zu anderen Dynamik-Strategien kombiniert diese Strategie die Vorteile sowohl des RSI als auch der Stochastischen Indikatoren, um kurzfristige Marktoscillationen genauer zu erfassen.
Der Kernindikator der Strategie ist der stochastische RSI.
Der Stochastische RSI = (RSI - RSI niedrig) / (RSI hoch - RSI niedrig)
Der RSI wird unter Verwendung des Parameters lengthRSI (Standard 12) und der stochastische RSI unter Verwendung des Parameters lengthStoch (Standard 12) berechnet.
Wenn der Stochastic RSI höher als das lila gefüllte Gebiet ist, ist es das überkaufte Gebiet, dann gehen Sie kurz; wenn der Stochastic RSI niedriger als das lila gefüllte Gebiet ist, ist es das überverkaufte Gebiet, dann gehen Sie lang.
Darüber hinaus setzt die Strategie auch die gleitende Durchschnittsfilterbedingung fest. Nur wenn die schnelle EMA höher als die langsame EMA ist, können Sie eine Long-Position eröffnen; nur wenn die schnelle EMA niedriger als die langsame EMA ist, können Sie eine Short-Position eröffnen. Dies vermeidet den Gegentrendhandel.
Im Vergleich zu einer einzigen RSI-Strategie kombiniert diese Strategie den Stochastischen Indikator, um überkaufte/überverkaufte Bereiche klarer zu identifizieren und somit die Zuverlässigkeit der Signale zu verbessern.
Im Vergleich zu einer einzigen Stochastischen Strategie verwendet diese Strategie den RSI als Eingabedatenquelle des Stochastischen, die etwas Rauschen filtern und das Signal zuverlässiger machen kann.
Der gleitende Durchschnittsfilter ist so eingestellt, dass sich die Konstruktion von Gegentrendpositionen effektiv verhindert und dadurch unnötige Verluste verringert werden.
Die Position Haltezeitverzögerung ist so eingestellt, dass sie nicht durch falsche Ausbrüche gestoppt wird.
Die Strategie verwendet hauptsächlich kurzfristige Indikatoren, ist daher nur für kurzfristige Operationen geeignet und kann langfristig nicht gut funktionieren.
Der Stochastic RSI-Indikator selbst hat eine gewisse Verzögerung und kann nach drastischen Kursänderungen kurzfristig Signale verpassen.
In schwankenden Märkten kann der stochastische RSI zu mehrfachen Durchdringungen von überkauften/überverkauften Bereichen führen, was zu Überhandelungen und erhöhten Transaktionskosten führen kann.
Verschiedene Parameterkombinationen können getestet werden, um die Längen-, K- und D-Werte des stochastischen RSI weiter zu optimieren.
Verschiedene RSI-Längenparameter können getestet werden, um einen geeigneteren RSI-Zyklus zu finden.
Versuchen Sie, sie mit anderen Indikatoren zu kombinieren, um die Signalgenauigkeit weiter zu verbessern, wie z. B. MACD, Bollinger Bands usw.
Versuchen Sie, verschiedene Verzögerungsparameter in Position zu halten, um einen geeigneteren Ausstiegszeitpunkt zu finden.
Dieser Artikel beschreibt die Konstruktionsprinzipien, Vorteile, Risiken und Optimierungsideen einer Dynamikstrategie auf der Grundlage des stochastischen RSI-Indikators. Verglichen mit Einzelindikatorstrategien nutzt diese Strategie die Stärken sowohl des RSI als auch des Stochastischen, um kurzfristige Überkauf/Überverkaufsphänomene auf dem Markt für den Umkehrhandel klarer und zuverlässiger zu identifizieren. Durch Parameteroptimierung und Indikatorkombinationen können weitere Leistungsverbesserungen erwartet werden.
/*backtest start: 2023-11-25 00:00:00 end: 2023-12-25 00:00:00 period: 1h basePeriod: 15m 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/ // © Drun30 (Federico Magnani) //@version=4 //STRATEGIA PRINCIPALE capitaleIniziale=10000 var sizeordineInit= 50 // → % di capitale investita per ogni trade var deltaSize = 25 // → delta% di capitale investito se trade precedente è stato in perdita var sizeLimite = 100 //il trade non userà mai questa percentuale di capitale investito var sizeordine = sizeordineInit //Parametri ottimali 30 min usiShort=false usiLong=true ipercomprato=85.29 ipervenduto=30.6 // strategy("Momentum Strategy (V7.B.4)", initial_capital=capitaleIniziale, currency="USD", default_qty_type=strategy.percent_of_equity, commission_type=strategy.commission.percent, commission_value=0.1, slippage = 5, default_qty_value=sizeordineInit, overlay=false, pyramiding=0) backtest = input(title="------------------------Backtest Period------------------------", defval = false) start = timestamp(input(2020, "start year"), input(1, "start month"), input(1, "start day"), 00, 00) end = timestamp(input(0, "end year"), input(0, "end month"), input(0, "end day"), 00, 00) siamoindata=time > start?true:false if end > 0 siamoindata:=time > start and time <= end?true:false basicParameters = input(title="------------------------Basic Parameters------------------------", defval = false) smoothK = input(3, minval=1) smoothD = input(6, minval=1) lengthRSI = input(12, minval=1) src = input(close, title="RSI Source") rsi1 = rsi(src, lengthRSI) lengthStoch = input(12, minval=1) k = ema(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK) d = ema(k, smoothD) altezzaipercomprato= input(ipercomprato, title="Overbought Height", minval=1, type=input.float) altezzaipervenduto= input(ipervenduto, title="Oversold Height", minval=1,type=input.float) BarsDelay = input(6,title="Bars delay",minval=0) GambleSizing = input(true, title = "Gamble Sizing?",type=input.bool) gambleAdd = input(deltaSize,title="Gamble Add (%)",minval=0,type=input.integer) gambleLimit = input(sizeLimite,title="Gamble MAX (%)",minval=0,type=input.integer) if GambleSizing and strategy.closedtrades[0]>strategy.closedtrades[1] if strategy.losstrades[0]>strategy.losstrades[1] and sizeordine<gambleLimit sizeordine:=sizeordine+gambleAdd if strategy.wintrades[0]>strategy.wintrades[1] sizeordine:=sizeordineInit periodomediamobile_fast = input(1, title="Fast EMA length",minval=1) periodomediamobile_slow = input(60, title="Slow EMA length",minval=1) plot(k, color=color.blue) plot(d, color=color.orange) h0 = hline(altezzaipercomprato) h1 = hline(altezzaipervenduto) fill(h0, h1, color=color.purple, transp=80) // n=input(Vicinanzadalcentro,title="Vicinanza dal centro",minval=0) //sarebbe il livello di D in cui si acquista o si vende, maggiore è la vicinanza maggiore sarà la frequenza dei trades, SE 0 è DISABILITATO // siamoinipervenduto= d<=altezzaipervenduto and d<=d[n] and d>d[1]?true:false //and d<d[3] and d>d[1] // siamoinipercomprato= d>=altezzaipercomprato and d>=d[n] and d<d[1]?true:false //and d>d[3] and d<d[1] goldencross = crossover(k,d) deathcross = crossunder(k,d) // METTI VARIABILE IN CUI AVVIENE CROSSOVER O CROSSUNDER valoreoro = valuewhen(goldencross,d,0) valoremorte = valuewhen(deathcross,d,0) siamoinipervenduto = goldencross and valoreoro<=altezzaipervenduto?true:false//d<=altezzaipervenduto?true:false siamoinipercomprato = deathcross and valoremorte>=altezzaipercomprato?true:false//d>=altezzaipercomprato?true:false long_separator = input(title="------------------------LONG------------------------", defval = usiLong) sl_long_inp = input(10, title="Stop Loss LONG %", type=input.float) tp_long_inp = input(8, title="Take Profit LONG %",type=input.float) stop_level_long = strategy.position_avg_price * (1 - (sl_long_inp/100)) //strategy.position_avg_price corrisponde al prezzo con cui si è aperta la posizione take_level_long = strategy.position_avg_price * (1 + (tp_long_inp/100)) //BINANCE JSON_long = 'OPEN LONG: PUT THE JSON HERE FOR THE API CALL' JSON_chiusura = 'CLOSE POSITION: PUT THE JSON HERE FOR THE API CALL' webhookLong = JSON_long webhookClose= JSON_chiusura trendFilterL = input(title="TREND FILTER LONG?", defval = true) EMAfast=ema(close,periodomediamobile_fast) EMAslow=ema(close,periodomediamobile_slow) siamoinuptrend_ema=EMAfast>EMAslow?true:false //close>=EMAfast and EMAfast>EMAslow siamoinuptrend = siamoinuptrend_ema // CondizioneAperturaLong = siamoinipervenduto and siamoindata // and siamoinuptrend CondizioneAperturaLong = siamoinipervenduto and siamoindata and long_separator if trendFilterL CondizioneAperturaLong := siamoinipervenduto and siamoindata and long_separator and siamoinuptrend CondizioneChiusuraLong = siamoinipercomprato and siamoindata possiamoAprireLong=0 if trendFilterL and siamoinuptrend possiamoAprireLong:=5 plot(possiamoAprireLong,color=color.green) sonPassateLeBarreG = barssince(CondizioneAperturaLong) == BarsDelay?true:false sonPassateLeBarreD = barssince(CondizioneChiusuraLong) == BarsDelay?true:false haiUnLongAncoraAperto = false haiUnLongAncoraAperto := strategy.position_size>0?true:false // Se l'ultimo valore della serie "CondizioneAperturaLong" è TRUE, allora hai un long ancora aperto // Se l'ultimo valore della serie "CondizioneAperturaLong" è FALSE, allora: // Se l'ultimo valore della serie "CondizioneChiusuraLong" è TRUE, allora NON hai un long ancora aperto // Se l'ultimo valore della serie "CondizioneChiusuraLong" è FALSE, allora restituisce l'ultimo valore della serie "haiUnLongAncoraAperto" haiUnLongAncoraAperto_float = if(haiUnLongAncoraAperto==true) 10 else 0 plot(haiUnLongAncoraAperto_float,color=color.red) //FInché la linea rossa si trova a livello "1" allora c'è un ordine long in corso quantita = (sizeordine/100*(capitaleIniziale+strategy.netprofit))/valuewhen(haiUnLongAncoraAperto==false and CondizioneAperturaLong,close,0) plot(sizeordine,color=color.purple, linewidth=3) if strategy.position_size<=0 and CondizioneAperturaLong //and sonPassateLeBarreG and haiUnLongAncoraAperto==false strategy.opentrades==0 strategy.entry("Vamonos",strategy.long, alert_message=webhookLong, comment="OPEN LONG", qty=quantita) if strategy.position_size>0 //and sonPassateLeBarreD // and CondizioneChiusuraLong if siamoinuptrend == true and sonPassateLeBarreD strategy.close("Vamonos", alert_message=webhookClose, comment="CLOSE LONG") else if siamoinuptrend == false and CondizioneChiusuraLong strategy.close("Vamonos", alert_message=webhookClose, comment="CLOSE LONG") if strategy.position_size>0 and siamoindata strategy.exit("Vamonos", stop=stop_level_long, limit=take_level_long, comment="CLOSE LONG (LIMIT/STOP)") short_separator = input(title="------------------------SHORT------------------------", defval = usiShort) sl_short_inp = input(20, title="Stop Loss SHORT %") tp_short_inp = input(35, title="Take Profit SHORT %") stop_level_short = strategy.position_avg_price * (1 + (sl_short_inp/100)) take_level_short= strategy.position_avg_price * (1 - (tp_short_inp/100)) // BINANCE JSON_short = 'OPEN SHORT: PUT THE JSON HERE FOR THE API CALL' webhookShort = JSON_short trendFilterS = input(title="TREND FILTER SHORT?", defval = true) siamoindowntrend_ema=EMAfast<EMAslow?true:false //close<=EMAfast and EMAfast<EMAslow siamoindowntrend=siamoindowntrend_ema CondizioneAperturaShort = short_separator and siamoinipercomprato and siamoindata if trendFilterS CondizioneAperturaShort:=short_separator and siamoinipercomprato and siamoindata and siamoindowntrend CondizioneChiusuraShort = siamoinipervenduto and siamoindata sonPassateLeBarreGs = barssince(CondizioneAperturaShort) == BarsDelay?true:false sonPassateLeBarreDs = barssince(CondizioneChiusuraShort) == BarsDelay?true:false haiUnoShortAncoraAperto = false haiUnoShortAncoraAperto := strategy.position_size<0?true:false haiUnoShortAncoraAperto_float = if(haiUnoShortAncoraAperto==true) 15 else 0 plot(haiUnoShortAncoraAperto_float,color=color.purple) //FInché la linea viola si trova a livello "2" allora c'è un ordine short in corso if CondizioneAperturaShort and strategy.position_size>=0 //and haiUnoShortAncoraAperto==false strategy.entry("Andale",strategy.short,alert_message=webhookShort, comment="OPEN SHORT") if strategy.position_size<0 //and sonPassateLeBarreD // and CondizioneChiusuraLong if siamoindowntrend == true and sonPassateLeBarreDs strategy.close("Andale",alert_message=webhookClose, comment="CLOSE SHORT") else if siamoindowntrend == false and CondizioneChiusuraShort strategy.close("Andale",alert_message=webhookClose, comment="CLOSE SHORT") if strategy.position_size<0 and siamoindata strategy.exit("Andale", stop=stop_level_short, limit=take_level_short, comment="CLOSE SHORT (LIMIT/STOP)")