
La idea principal de esta estrategia es utilizar la identificación de la tendencia de la dirección de la banda de ruptura, en combinación con los límites fijos para el manejo del riesgo. La estrategia primero calcula el precio más alto y el precio más bajo en un determinado período, formando una banda de ruptura.
La estrategia se compone principalmente de cuatro partes: gestión de posiciones, identificación de bandas de ruptura, configuración de stop loss y cálculo de la cantidad.
En primer lugar, la estrategia es determinar si la posición actual está ocupada. Si ya está ocupada, no se generan nuevas señales.
En segundo lugar, la estrategia calcula los precios más altos y más bajos en un determinado período, formando una banda de ruptura. Cuando el precio se rompe desde el interior de la banda de ruptura hacia el exterior, se produce una señal de negociación. En concreto, si el precio rompe la banda de ruptura hacia arriba, se produce una señal de multiplicación; si el precio rompe la banda de ruptura hacia abajo, se produce una señal de ruptura.
Además, cuando se produce una señal múltiple, la estrategia establece el punto medio de la banda de ruptura como el punto de parada. Cuando se produce una señal de salida, también se establece el punto de parada. Para realizar el seguimiento de la parada, la estrategia también ajusta el punto de parada en tiempo real durante la tenencia de la posición.
Finalmente, la estrategia permite establecer una cantidad fija de stop loss. Cuando se produce la señal, la estrategia calcula la distancia entre el punto de stop loss y el precio actual, y luego, combinando factores como la unidad de cotización y el tipo de cambio, calcula la cantidad representada por el cambio de precio entre los puntos de stop loss.
Este es el principio básico de la estrategia. Identificar la dirección de la tendencia a través de la banda de ruptura y controlar el riesgo utilizando el stop loss fijo es la idea central de la estrategia.
Esta estrategia de parada fija de la banda de ruptura tiene las siguientes ventajas:
La estrategia es usar un monto fijo en lugar de una distancia fija. Esto evita el problema de que no se puede fijar el riesgo entre diferentes variedades debido a la diferencia en el valor de los puntos. Desde el punto de vista de la gestión de riesgos, el monto fijo en el stop loss es más avanzado.
La estrategia puede calcular inteligentemente el número de operaciones en función de la cantidad fija de stop loss, lo que hace que cada pérdida sea controlada, lo que permite un control razonable de la brecha de riesgo.
La identificación de breakouts es sencilla y efectiva. La identificación de bandas de breakouts es sencilla y directa, y permite identificar la dirección de la tendencia de manera efectiva. En comparación con solo romper un nivel de precio, la identificación de bandas de breakouts evita señales falsas que se desvían más de la dirección de la tendencia.
La estrategia permite ajustar en tiempo real la posición de sus paradas para seguir las paradas y ayudar a bloquear más ganancias.
Amplio alcance de aplicación. La estrategia se puede aplicar a cualquier variedad y, siempre que se establezcan los parámetros, se puede realizar un control de riesgo de pérdidas fijas, lo que tiene una aplicación muy amplia.
La estructura del código es clara. La estructura del código de la estrategia es razonablemente clara, los módulos funcionales están bien descifrados, lo que facilita la comprensión y la optimización posterior.
A pesar de las ventajas mencionadas, la estrategia también presenta ciertos riesgos que deben tenerse en cuenta:
No se puede determinar la calidad de la forma de ruptura. La estrategia no puede determinar la calidad de la forma de ruptura, y puede generar señales de baja calidad. Se necesita filtrar en combinación con otros indicadores.
Los paros fijos pueden ser demasiado mecánicos. Los precios del mercado suelen tener características de salto en altura, los paros fijos pueden depender demasiado de las reglas y no pueden ajustarse con flexibilidad.
No se puede limitar la frecuencia de las transacciones. La estrategia no puede limitar la frecuencia de las transacciones, y es posible que se juegue con demasiada frecuencia. La restricción de la frecuencia debe combinarse con otras reglas.
La fijación del límite de pérdidas fijas depende de los parámetros. La fijación del límite de pérdidas fijas se refiere al control de la brecha general, que requiere una configuración razonable en función del tamaño del capital, las preferencias de riesgo, etc.
La dirección de la ruptura puede generar una señal de ruptura errónea. Cuando hay una oscilación o una reorientación en el precio, puede generar una señal de ruptura errónea. La optimización debe combinarse con múltiples condiciones.
La falta de paradas. La estrategia actual no tiene paradas, por lo que no se puede determinar el beneficio de manera activa. Esto puede conducir a un beneficio no deseable.
En cuanto a los riesgos mencionados, podemos optimizar en los siguientes aspectos:
Añadir indicadores para juzgar la forma, filtrar la calidad de la señal. Por ejemplo, MACD, KD, etc.
En combinación con los indicadores de fuerza de ruptura, se evalúa la calidad de la ruptura. Por ejemplo, se puede determinar la fuerza de la ruptura a través del cambio en la cantidad de transacciones.
Aumentar los límites de la frecuencia de apertura de la posición. Por ejemplo, solo se puede negociar una vez al día o reglas similares.
Optimización de la lógica de configuración de stop loss fijo. Por ejemplo, cambiar el stop loss por ciento en función de un umbral específico.
Añadir otras condiciones de filtración, como el aumento del stop loss, la volatilidad de los precios, etc.
Agregar estrategias de frenado. Por ejemplo, frenado cuando se acerca a la resistencia.
De acuerdo con el análisis anterior, la estrategia puede ser optimizada en los siguientes aspectos:
Aumentar las condiciones de filtración y mejorar la calidad de la señal. Se pueden agregar varios indicadores técnicos para juzgar la calidad de la tendencia y evitar señales de ruptura no deseadas. También se puede juzgar la intensidad de la ruptura.
Optimización de las estrategias de stop loss para que sean más flexibles. Se puede cambiar a stop loss proporcional después de una cierta distancia de reajuste de la ruptura. También se puede optimizar la distancia de stop loss en tiempo real en función de la fluctuación.
Controlar la frecuencia de las transacciones y evitar el exceso de operaciones. Se pueden establecer condiciones de filtrado para un período de tiempo o una cantidad de veces, lo que reduce la frecuencia de las transacciones.
En combinación con los indicadores de tendencia, se puede elegir la hora de entrada. Por ejemplo, se puede optimizar para volver a entrar después de la confirmación de la tendencia.
Optimización de la estrategia de stop loss y mejora de la rentabilidad. Se puede establecer un objetivo de ganancias, movimiento de stop loss, stop loss de fluctuación, etc.
Optimización de la configuración de los parámetros de riesgo. Se puede configurar una combinación de parámetros más óptima en función de los resultados de la retroalimentación, como el monto fijo de stop loss, el ciclo de ruptura, etc.
Mejora de la estructura del código, mejora de la extensibilidad. Descomposición de los módulos de generación de señales, filtración, control de viento y ganancia.
Probar más variedades en el espacio de arbitraje. Evaluar las ventajas de arbitraje de diferentes combinaciones de variedades.
La optimización de estos múltiples aspectos puede aumentar aún más la estabilidad y la rentabilidad de esta estrategia de deterioro de pérdidas. Al mismo tiempo, también se puede construir una base para la futura expansión a más combinaciones de estrategias.
La estrategia general es razonable, utiliza la identificación de tendencias de la banda de ruptura y utiliza el límite de la cantidad fija para controlar el riesgo. Esto es progresista en la gestión del riesgo. La idea de calcular el número de operaciones al mismo tiempo también es razonable y puede controlar cada pérdida. Pero la estrategia puede optimizarse en muchos aspectos para mejorar la calidad de la señal, la flexibilidad de la estrategia de parada y la igualdad de ganancias.
/*backtest
start: 2023-10-26 00:00:00
end: 2023-10-28 03:00:00
period: 10m
basePeriod: 1m
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/
//@version=4
//@author=Takazudo
strategy("Fixed price SL",
overlay=true,
default_qty_type=strategy.fixed,
initial_capital=0,
currency=currency.USD)
var COLOR_TRANSPARENT = color.new(#000000, 100)
var COLOR_ENTRY_BAND = color.new(#43A6F5, 30)
//============================================================================
// config
//============================================================================
// Money management
_g1 = 'Money management'
var config_riskPrice = input(100, minval=1, title="Risk price for each entry", group=_g1)
var config_depositCurrency = input(title="Deposit currency", type=input.string, defval="USD", options=["USD"], group=_g1)
// Entry strategy
_g2 = 'Entry strategy'
var config_entryBandBars = input(defval = 100, title = "Entry band bar count", minval=1, group=_g2)
// Backtesting range
_g3 = 'Backtesting range'
fromYear = input(defval = 2018, title = "From Year", minval = 1970, group=_g3)
fromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12, group=_g3)
fromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31, group=_g3)
toYear = input(defval = 2020, title = "To Year", minval = 1970, group=_g3)
toMonth = input(defval = 12, title = "To Month", minval = 1, maxval = 12, group=_g3)
toDay = input(defval = 31, title = "To Day", minval = 1, maxval = 31, group=_g3)
//============================================================================
// exchange caliculations
//============================================================================
// mico pip size caliculation
// ex1: AUDCAD -> 0.0001
// ex2: USDJPY -> 0.01
f_calcMicroPipSize() =>
_base = syminfo.basecurrency
_quote = syminfo.currency
_result = 0.0001
if _quote == 'JPY'
_result := _result * 100
if _base == 'BTC'
_result := _result * 100
_result
// convert price to pips
f_convertPriceToPips(_price) =>
_microPipSize = f_calcMicroPipSize()
_price / _microPipSize
// caliculate exchange rate between deposit and quote currency
f_calcDepositExchangeSymbolId() =>
_result = ''
_deposit = config_depositCurrency
_quote = syminfo.currency
if (_deposit == 'USD') and (_quote == 'USD')
_result := na
if (_deposit == 'USD') and (_quote == 'AUD')
_result := 'OANDA:AUDUSD'
if (_deposit == 'EUR') and (_quote == 'USD')
_result := 'OANDA:EURUSD'
if (_deposit == 'USD') and (_quote == 'GBP')
_result := 'OANDA:GBPUSD'
if (_deposit == 'USD') and (_quote == 'NZD')
_result := 'OANDA:NZDUSD'
if (_deposit == 'USD') and (_quote == 'CAD')
_result := 'OANDA:USDCAD'
if (_deposit == 'USD') and (_quote == 'CHF')
_result := 'OANDA:USDCHF'
if (_deposit == 'USD') and (_quote == 'JPY')
_result := 'OANDA:USDJPY'
_result
// Let's say we need CAD to USD exchange
// However there's only "OANDA:USDCAD" symbol.
// Then we need to invert the exhchange rate.
// this function tells us whether we should invert the rate or not
f_calcShouldInvert() =>
_result = false
_deposit = config_depositCurrency
_quote = syminfo.currency
if (_deposit == 'USD') and (_quote == 'CAD')
_result := true
if (_deposit == 'USD') and (_quote == 'CHF')
_result := true
if (_deposit == 'USD') and (_quote == 'JPY')
_result := true
_result
// caliculate how much quantity should I buy or sell
f_calcQuantitiesForEntry(_depositExchangeRate, _slPips) =>
_microPipSize = f_calcMicroPipSize()
_priceForEachPipAsDeposit = _microPipSize * _depositExchangeRate
_losePriceOnSl = _priceForEachPipAsDeposit * _slPips
floor(config_riskPrice / _losePriceOnSl)
//============================================================================
// Quantity caliculation
//============================================================================
depositExchangeSymbolId = f_calcDepositExchangeSymbolId()
// caliculate deposit exchange rate
rate = security(depositExchangeSymbolId, timeframe.period, hl2)
shouldInvert = f_calcShouldInvert()
depositExchangeRate = if config_depositCurrency == syminfo.currency
// if USDUSD, no exchange of course
1
else
// else, USDCAD to CADUSD invert if we need
shouldInvert ? (1 / rate) : rate
//============================================================================
// Range Edge caliculation
//============================================================================
f_calcEntryBand_high() =>
_highest = max(open[3], close[3])
for i = 4 to (config_entryBandBars - 1)
_highest := max(_highest, open[i], close[i])
_highest
f_calcEntryBand_low() =>
_lowest = min(open[3], close[3])
for i = 4 to (config_entryBandBars - 1)
_lowest := min(_lowest, open[i], close[i])
_lowest
entryBand_high = f_calcEntryBand_high()
entryBand_low = f_calcEntryBand_low()
entryBand_height = entryBand_high - entryBand_low
plot(entryBand_high, color=COLOR_ENTRY_BAND, linewidth=1)
plot(entryBand_low, color=COLOR_ENTRY_BAND, linewidth=1)
rangeBreakDetected_long = entryBand_high < close
rangeBreakDetected_short = entryBand_low > close
shouldMakeEntryLong = (strategy.position_size == 0) and rangeBreakDetected_long
shouldMakeEntryShort = (strategy.position_size == 0) and rangeBreakDetected_short
//============================================================================
// SL & Quantity
//============================================================================
var sl_long = hl2
var sl_short = hl2
entryQty = 0
slPips = 0.0
// just show info bubble
f_showEntryInfo(_isLong) =>
_str =
'SL pips: ' + tostring(slPips) + '\n' +
'Qty: ' + tostring(entryQty)
_bandHeight = entryBand_high - entryBand_low
_y = _isLong ? (entryBand_low + _bandHeight * 1/4) : (entryBand_high - _bandHeight * 1/4)
_style = _isLong ? label.style_label_up : label.style_label_down
label.new(bar_index, _y, _str, size=size.large, style=_style)
if shouldMakeEntryLong
sl_long := (entryBand_high + entryBand_low) / 2
slPips := f_convertPriceToPips(close - sl_long)
entryQty := f_calcQuantitiesForEntry(depositExchangeRate, slPips)
if shouldMakeEntryShort
sl_short := (entryBand_high + entryBand_low) / 2
slPips := f_convertPriceToPips(sl_short - close)
entryQty := f_calcQuantitiesForEntry(depositExchangeRate, slPips)
// trailing SL
if strategy.position_size > 0
sl_long := max(sl_long, entryBand_low)
if strategy.position_size < 0
sl_short := min(sl_short, entryBand_high)
//============================================================================
// backtest duration
//============================================================================
// Calculate start/end date and time condition
startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00)
finishDate = timestamp(toYear, toMonth, toDay, 00, 00)
//============================================================================
// make entries
//============================================================================
if (true)
if shouldMakeEntryLong
strategy.entry(id="Long", long=true, stop=close, qty=entryQty)
f_showEntryInfo(true)
if shouldMakeEntryShort
strategy.entry(id="Short", long=false, stop=close, qty=entryQty)
f_showEntryInfo(false)
strategy.exit('Long-SL/TP', 'Long', stop=sl_long)
strategy.exit('Short-SL/TP', 'Short', stop=sl_short)
//============================================================================
// plot misc
//============================================================================
sl = strategy.position_size > 0 ? sl_long :
strategy.position_size < 0 ? sl_short : na
plot(sl, color=color.red, style=plot.style_cross, linewidth=2, title="SL")
value_bgcolor = rangeBreakDetected_long ? color.green :
rangeBreakDetected_short ? color.red : COLOR_TRANSPARENT
bgcolor(value_bgcolor, transp=95)