Estrategia de trading con oscilador de impulso estocástico RSI


Fecha de creación: 2023-12-26 12:11:21 Última modificación: 2023-12-26 12:11:21
Copiar: 0 Número de Visitas: 614
1
Seguir
1621
Seguidores

Estrategia de trading con oscilador de impulso estocástico RSI

Descripción general

Este artículo trata principalmente sobre una estrategia de comercio de movimiento basado en el indicador RSI estocástico. Esta estrategia utiliza un indicador técnico de período más corto (por ejemplo, 30 minutos) para tomar decisiones de negociación en función de si el RSI estocástico ha entrado en una zona de sobreventa o sobreventa. En comparación con otras estrategias de movimiento, esta estrategia combina las ventajas de ambos indicadores, el RSI y el estocástico, para capturar con mayor precisión las fluctuaciones de corta duración en el mercado.

Principio de estrategia

El indicador central de la estrategia es el RSI estocástico. La fórmula para calcular el RSI estocástico es:

El RSI estocástico = (RSI - bajo RSI) / (RSI - alto RSI - bajo RSI) * 100

El RSI se calcula con el parámetro lengthRSI (default12), mientras que el RSI estocástico se calcula con el parámetro lengthStoch (default12).

Cuando el RSI estocástico está por encima de la zona de relleno púrpura es zona de sobrecompra, en cuyo caso se hace un descuento; cuando el RSI estocástico está por debajo de la zona de relleno púrpura es zona de sobreventa, en cuyo caso se hace un descuento.

Además, la estrategia también establece condiciones de filtro de línea uniforme. Sólo se puede abrir una posición más alta cuando el EMA rápido es superior al EMA lento; solo se puede abrir una posición baja cuando el EMA rápido es inferior al EMA lento. Esto evita el comercio de contravalor.

Ventajas estratégicas

En comparación con la estrategia RSI individual, la estrategia combina el indicador estocástico para identificar con mayor claridad las zonas de sobreventa y sobrecompra, lo que mejora la fiabilidad de la señal.

En comparación con una sola estrategia estocástica, la estrategia utiliza el RSI como fuente de datos de entrada estocástica, que puede filtrar parte del ruido y hacer que la señal sea más confiable.

Se establecen condiciones de filtración uniformes que evitan la construcción de un almacén de resistencia, lo que reduce las pérdidas innecesarias.

El retraso en el tiempo de mantenimiento de la posición evita que se detenga por una falsa brecha.

Riesgo estratégico

La estrategia utiliza principalmente indicadores de corto período, por lo que solo es adecuada para operaciones de línea corta y puede no ser efectiva en la línea larga.

El indicador Stochastic RSI produce un cierto retraso en sí mismo, y puede perderse una señal después de un cambio drástico en los precios a corto plazo.

En situaciones de crisis, el RSI produce varios cruces de zona de sobreventa y sobrecompra, lo que puede aumentar el costo de la operación.

Dirección de optimización de la estrategia

  1. Se pueden probar diferentes combinaciones de parámetros para optimizar aún más la longitud, los valores K y D del RSI estocástico.

  2. Se pueden probar diferentes parámetros de longitud de RSI para encontrar la longitud de ciclo RSI más adecuada.

  3. Se puede combinar con otros indicadores para mejorar aún más la precisión de la señal, como el MACD, las Bandas de Bollinger, etc.

  4. Se pueden probar diferentes parámetros de retardo de tiempo de tenencia para encontrar el tiempo de salida más adecuado.

Resumir

Este artículo describe en detalle los principios de construcción, las ventajas, los riesgos y las ideas de optimización de una estrategia dinámica basada en un indicador RSI estocástico. En comparación con una estrategia de un solo indicador, esta estrategia utiliza al mismo tiempo las ventajas del RSI y el estocástico para identificar con mayor claridad y confiabilidad los fenómenos de sobreventa y sobreventa a corto plazo en el mercado y, por lo tanto, invertir el comercio.

Código Fuente de la Estrategia
/*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)")