Estrategia de trading con desviación estándar ponderada por media móvil


Fecha de creación: 2023-11-24 13:54:58 Última modificación: 2023-11-24 13:54:58
Copiar: 0 Número de Visitas: 773
1
Seguir
1617
Seguidores

Estrategia de trading con desviación estándar ponderada por media móvil

Descripción general

Esta estrategia utiliza un indicador de diferencia estándar ponderado, combinado con un promedio móvil, para realizar operaciones de tendencia en criptomonedas. La estrategia calcula el canal de diferencia estándar ponderada del precio en función del precio de cierre y el volumen de transacciones en un período determinado.

Principio de estrategia

En el código se definen dos funciones personalizadas, cada una de las cuales tiene una diferencia estándar ponderada de la secuencia de tiempo y de la aristocracia. Los pasos principales son:

  1. Cálculo del precio medio ponderado basado en el precio de cierre y el volumen de transacciones
  2. Calcula el cuadrado de la diferencia entre cada línea K y el promedio
  3. Calculación de la diferencia según el promedio ajustado por el volumen y el peso de la muestra
  4. El cuadro abierto tiene una diferencia estándar.

De esta manera, se obtiene un canal cuyo centro está en el promedio ponderado y cuya distancia hacia arriba y hacia abajo es una diferencia estándar. Hacer más cuando el precio rompe el fondo del canal desde abajo; y hacer menos cuando lo hace desde arriba.

Análisis de las ventajas

La mayor ventaja de esta estrategia es que combina las medias móviles y el análisis de la volatilidad. Las medias móviles determinan la dirección de la tendencia del mercado, la diferencia estándar define un intervalo razonable, ambas se verifican entre sí y tienen una mayor fiabilidad. Además, el peso de la transacción puede filtrar falsas rupturas y la probabilidad de ruptura real es mayor.

La estrategia también establece un punto de parada de pérdidas, lo que es útil para capturar la tendencia y evitar que la reversión cause una pérdida excesiva. Esto es algo que muchos novatos no pueden dominar.

Análisis de riesgos

El principal riesgo es que el mercado puede fluctuar fuertemente. En este caso, el canal de diferencia estándar también puede fluctuar mucho, lo que dificulta el juicio. Además, si el ciclo de selección es demasiado corto y es fácil de ser interrumpido por el ruido, la tasa de error es alta.

La contra-medida es ajustar adecuadamente los parámetros de ciclo y suavizar la curva. También se puede considerar la combinación de otros indicadores, como el RSI, para aumentar el efecto de confirmación de la ruptura.

Dirección de optimización

  1. Parámetros de optimización de ciclo: se pueden probar diferentes ciclos de 5 minutos, 15 minutos y 30 minutos para encontrar la combinación óptima
  2. Optimización de la proporción de paradas de pérdidas. Prueba diferentes paradas de pérdidas para obtener la mejor rentabilidad.
  3. Aumentar las condiciones de filtración, como la combinación de volumen de tráfico, para evitar pérdidas falsas.
  4. Aumentar los indicadores de valor, como la posición del precio de cierre, la longitud de la línea de sombra y la confirmación de la entidad de la línea K, para reducir el error

Resumir

Esta estrategia utiliza con éxito el indicador de diferencia estándar ponderado, con el apoyo de medias móviles para determinar la dirección, para lograr el seguimiento de la tendencia de las criptomonedas. Al mismo tiempo, la configuración razonable de los paros de pérdida ayuda a capturar el ritmo del mercado y evitar que la inversión excesiva traiga pérdidas.

Código Fuente de la Estrategia
/*backtest
start: 2023-11-16 00:00:00
end: 2023-11-23 00:00:00
period: 45m
basePeriod: 5m
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/
// © rumpypumpydumpy   © cache_that_pass

//@version=4
strategy("[cache_that_pass] 1m 15m Function - Weighted Standard Deviation", overlay=true, pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=20, initial_capital=10000, commission_type=strategy.commission.percent, commission_value=0.075)

f_weighted_sd_from_series(_src, _weight, _n) => //{
//  @function: Calculates weighted mean, variance, standard deviation, MSE and RMSE from time series variables
//  @parameters:
//      _src: time series variable of sample values
//      _weight: time series of corresponding weight values.
//      _n : number of samples
    _xw = _src * _weight
    _sum_weight = sum(_weight, _n)
    _mean = sum(_xw, _n) / _sum_weight
    float _sqerror_sum = 0
    int _nonzero_n = 0
    for _i = 0 to _n - 1
        _sqerror_sum := _sqerror_sum + pow(_mean - _src[_i], 2) * _weight[_i]
        _nonzero_n := _weight[_i] != 0 ? _nonzero_n + 1 : _nonzero_n
    _variance = _sqerror_sum / ((_nonzero_n - 1) * _sum_weight / _nonzero_n)
    _dev = sqrt(_variance)
    _mse = _sqerror_sum / _sum_weight
    _rmse = sqrt(_mse)
    [_mean, _variance, _dev, _mse, _rmse]
//}
// -----------------------------------------------------------------------------

f_weighted_sd_from_arrays(_a_src, _a_weight, _n) => //{
//  @function: Calculates weighted mean, variance, standard deviation, MSE and RMSE from arrays
//  Expects index 0 of the arrays to be the most recent sample and weight values!
//  @parameters:
//      _a_src: array of sample values
//      _a_weight: array of corresponding weight values.
//      _n : number of samples
    float _mean = na, float _variance = na, float _dev = na, float _mse = na
    float _rmse = na, float _sqerror_sum = na, float _sum_weight = na
    float[] _a_xw = array.new_float(_n)
    int _nonzero_n = 0
    if array.size(_a_src) >= _n
        _sum_weight := 0
        _sqerror_sum := 0
        for _i = 0 to _n - 1
            array.set(_a_xw, _i, array.get(_a_src, _i) * array.get(_a_weight, _i))
            _sum_weight := _sum_weight + array.get(_a_weight, _i)
            _nonzero_n := array.get(_a_weight, _i) != 0 ? _nonzero_n + 1 : _nonzero_n
        _mean := array.sum(_a_xw) / _sum_weight
        for _j = 0 to _n - 1
            _sqerror_sum := _sqerror_sum + pow(_mean - array.get(_a_src, _j), 2) * array.get(_a_weight, _j)
        _variance := _sqerror_sum / ((_nonzero_n - 1) * _sum_weight / _nonzero_n)
        _dev := sqrt(_variance)
        _mse := _sqerror_sum / _sum_weight
        _rmse := sqrt(_mse)
    [_mean, _variance, _dev, _mse, _rmse]
//}


// -----------------------------------------------------------------------------
// Example usage : 
// -----------------------------------------------------------------------------

len = input(20)

// -----------------------------------------------------------------------------
// From series :
// -----------------------------------------------------------------------------
[m, v, d, mse, rmse] = f_weighted_sd_from_series(close, volume, len)


plot(m, color = color.blue)
plot(m + d * 2, color = color.blue)
plot(m - d * 2, color = color.blue)
// -----------------------------------------------------------------------------



// -----------------------------------------------------------------------------
// From arrays : 
// -----------------------------------------------------------------------------
var float[] a_src = array.new_float()
var float[] a_weight = array.new_float()

if barstate.isfirst
    for i = 1 to len
        array.unshift(a_weight, i)

array.unshift(a_src, close)

if array.size(a_src) > len
    array.pop(a_src)

[a_m, a_v, a_d, a_mse, a_rmse] = f_weighted_sd_from_arrays(a_src, a_weight, len)

plot(a_m, color = color.orange)
plot(a_m + a_d * 2, color = color.orange)
plot(a_m - a_d * 2, color = color.orange)
// -----------------------------------------------------------------------------


series_text = "Mean : " + tostring(m) + "\nVariance : " + tostring(v) + "\nSD : " + tostring(d) + "\nMSE : " + tostring(mse) +  "\nRMSE : " + tostring(rmse)
array_text = "Mean : " + tostring(a_m) + "\nVariance : " + tostring(a_v) + "\nSD : " + tostring(a_d) + "\nMSE : " + tostring(a_mse) +  "\nRMSE : " + tostring(a_rmse)
debug_text = "Volume weighted from time series : \n" + series_text + "\n\nLinearly weighted from arrays : \n" + array_text

//debug = label.new(x = bar_index, y = close, text = debug_text, style = label.style_label_left)
//.delete(debug[1])

//test strategy
if low <= (m - d * 2)
    strategy.entry("LE", strategy.long)
if high >= (m + d * 2)
    strategy.entry("SE", strategy.short)

// User Options to Change Inputs (%)
stopPer = input(3.11, title='Stop Loss %', type=input.float) / 100
takePer = input(7.50, title='Take Profit %', type=input.float) / 100

// Determine where you've entered and in what direction
longStop = strategy.position_avg_price * (1 - stopPer)
shortStop = strategy.position_avg_price * (1 + stopPer)
shortTake = strategy.position_avg_price * (1 - takePer)
longTake = strategy.position_avg_price * (1 + takePer)

if strategy.position_size > 0 
    strategy.exit(id="Close Long", stop=longStop, limit=longTake)
//    strategy.close("LE", when = (longStop) or (longTake), qty_percent = 100)
if strategy.position_size < 0 
    strategy.exit(id="Close Short", stop=shortStop, limit=shortTake)
//    strategy.close("SE", when = (shortStop) or (shortTake), qty_percent = 100)